/*****************************************************************************/
/*!	\file		IEC61850API.h
 *	\brief		IEC61850 API header file
 *	\par		Dalian Yunxing Tech Co., Ltd.
 *
 *				Dalian, China
 *				Phone: +86 (411) 8825 4852
 *				Email: yx@yunxing.tech
 */
/*****************************************************************************/
#ifndef IEC61850_INCLUDED
#define IEC61850_INCLUDED 1

#include "sysctype.h"
#include "IEC61850Types.h"

/*
Library Control complier options

In a windows environment

	if PIS10_STATIC is defined then the library will be complied for static linking

	For making a DLL define PIS10_EXPORTS
	For using the DLL no NOT define PIS10_EXPORTS
*/

#if defined(WIN32) || defined(WIN64)
#ifdef PIS10_STATIC
#define PIS10_API
#else
#if defined(PIS10_EXPORTS) || defined(DLL_EXPORT)
#define PIS10_API __declspec(dllexport)
#else
#define PIS10_API __declspec(dllimport)
#endif
#endif
#else
#define PIS10_API
#endif

/*!	\brief	YX-PIS 版本号 */
#define YX_PIS_VERSION         "V3.1.8"

/*!
 *	\defgroup	DataAttributeAccess	数据属性访问
 *	\defgroup	Management			IEC61850对象管理
 *	\defgroup	Time				时间与日期
 *	\defgroup	ModelData			模型和数据
 *	\defgroup	DataSet				数据集
 *	\defgroup	ControlBlock		控制块
 *	\defgroup	BRCB				缓存报告控制块
 *	\defgroup	URCB				非缓存报告控制块
 *	\defgroup	LCB					日志控制块
 *	\defgroup	SGCB				定值组控制块
 *	\defgroup	Report				报告
 *	\defgroup	Control				控制
 *	\defgroup	File				文件
 *	\defgroup	Support				支持
 */


#ifdef __cplusplus
extern "C" {
#endif
/*!	\brief	该接口用于创建 IEC61850 客户端 / 服务端 对象。
	\details
	该接口以 IEC61850 对象属性参数 `IEC61850_Parameters` 作为入参，<br>
	并按照属性参数的配置创建对应角色（客户端 / 服务端）的 IEC61850 对象。

	\ingroup	Management

	\param[in]		param		IEC61850 对象的属性参数
	\param[in,out]	errorCode	错误码。<br>如果 IEC61850 对象创建成功，则值为 #IEC61850_ERROR_NONE (0)；<br>
								如果 IEC61850 对象创建失败，则值为其他非 0 值的 #IEC61850_ErrorCode 错误码。

	\return	IEC61850 对象创建成功，将返回创建的 IEC61850 对象；<br>
			IEC61850 对象创建失败，则返回 NULL。同时，errorCode 将返回具体的错误码。

	\see	IEC61850_Free()

	<b>示例</b>

	创建服务端实例：
	\code
	IEC61850_ErrorCode error = S_OK;
	IEC61850 server = NULL;
	IEC61850_Parameters param = { 0 };	// must be initialized to zero value

	param.clientServerFlag	= IEC61850_SERVER;		// This is a IEC 61850 Server
	param.Ed1_Ed2_Flag		= IEC61850_Edition2;	// Set the IEC61850 Edition
	param.options			= IEC61850_OPTION_NONE;	// No options set
	param.cmdTermTimeout	= 0;					// Command Termination timeout 0 will default to 10 seconds
	param.fnReadCallback	= ReadFunction;			// Assign Read Callback Function
	param.fnWriteCallback	= WriteFunction;		// Assign Write Callback Function
	param.fnSelectCallback	= NULL;					// Ignoring Select commands
	param.fnOperateCallback	= OperateFunction;		// Assign Operate Callback Function
	param.fnCancelCallback	= NULL;					// Ignoring Cancel commands

	server = IEC61850_Create(&param, &error);
	if (!server) {
		printf("Failed to create IEC61850 server: %s (%d)", IEC61850_ErrorString(error), error);
	}
	\endcode

	创建客户端实例：
	\code
	IEC61850_ErrorCode error = S_OK;
	IEC61850 client = NULL;
	IEC61850_Parameters param = { 0 };	// must be initialized to zero value

	param.clientServerFlag	= IEC61850_CLIENT;		// This is a IEC 61850 Client
	param.options			= IEC61850_OPTION_NONE;	// No options set
	param.fnUpdateCallback	= UpdateFunction;		// Assign Update Callback Function for Client

	client = IEC61850_Create(&param, &error);
	if (!client) {
		printf("Failed to create IEC61850 client: %s (%d)", IEC61850_ErrorString(error), error);
	}
	\endcode
*/
PIS10_API IEC61850 IEC61850_Create(IEC61850_Parameters* param, IEC61850_ErrorCode* errorCode);

/*!	\brief	该接口用于删除和释放 `IEC61850_Create()` 创建的 IEC61850 对象和相关资源。
	\details
	应在 `IEC61850_Stop()` 调用之后调用。

	\ingroup	Management

	\param[in]	iec61850	IEC61850 对象。<br>由 `IEC61850_Create()` 创建。

	\return	错误码。<br>
			成功则返回 #IEC61850_ERROR_NONE (0)；<br>
			失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	\attention
	用于 `IEC61850_SetUserData()` 接口的自定义用户数据资源，不会被该接口释放，需自行管理其生命周期。

	\see	IEC61850_Create()

	<b>示例</b>
	\code
	IEC61850_ErrorCode error = S_OK;
	error = IEC61850_Free(iec61850);	// 'iec61850' is the IEC61850 instance created by IEC61850_Create()
	if (error != S_OK) {
		printf("Failed to free IEC61850 object: %s (%d)", IEC61850_ErrorString(error), error);
	}
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_Free(IEC61850 iec61850);

/*!	\brief	该接口用于为指定的 IEC61850 对象加载模型文件。
	\details
	以 IEC61850_Create() 创建的 IEC61850 对象、以及模型文件作为入参，调用后，IEC61850 对象将按指定的模型文件来加载。

	\ingroup	Management

	\param[in]	iec61850	IEC61850 对象。<br>由 IEC61850_Create() 创建。
	\param[in]	sclFileName	要加载的模型文件。模型文件只能是 cid 文件。<br>
							需要包含基于协议栈进程所在目录的相对文件路径，以及文件后缀名。<br>
							例如：\"./cms-cid/server.cid\"，\"./cms-cid/client.cid\"。

	\return	错误码<br>
			模型文件加载成功，则返回 `#IEC61850_ERROR_NONE` (0)<br>
			模型文件加载失败，则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。 

	\attention
	如果想更改 IEC61850 对象加载的模型文件，不能直接二次调用该接口。<br>
	必须先删除当前的 IEC61850 对象（通过 #IEC61850_Free() 删除），<br>
	再重新创建新的 IEC61850 对象（通过 #IEC61850_Create() 创建），<br>
	再通过该接口为新的 IEC61850 对象指定新的模型文件。

	<b>示例</b>
	\code
	IEC61850_ErrorCode error = S_OK;
	error = IEC61850_LoadSCLFile(iec61850, "./cms-cid/server.cid");	// 'iec61850' is the IEC61850 instance created by IEC61850_Create()
	if (error != S_OK) {
		printf("Failed to load SCL file: %s (%d)", IEC61850_ErrorString(error), error);
	}
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_LoadSCLFile(IEC61850 iec61850, const char* sclFileName);

/*!	\brief	为指定的 IEC61850 客户端对象加载服务端的模型文件(支持多文件）
	\details
	该接口由客户端使用，用于让客户端直接加载服务端的模型，无需制作客户端的模型。<br>
	指定的 sclList 为服务端的 cid、scd 文件列表，<br>
	客户端的接入信息，通过外部的客户端配置文件 client.ini 配置，这一步是必须要做的。

	\ingroup	Management

	\param[in]	client		IEC61850 对象。对象角色必须是客户端 IEC61850_CLIENT
	\param[in]	sclList		要连接的服务端的模型文件列表。<br>
							模型文件只能是 cid，scd 文件。<br>
							需要包含基于协议栈进程所在目录的相对文件路径，以及文件后缀名。<br>
							例如：\"./cms-cid/server.cid\"。
	\return	错误码<br>
			模型文件加载成功，则返回 `#IEC61850_ERROR_NONE` (0)<br>
			模型文件加载失败，则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	\attention
	如果想更改 IEC61850 对象加载的模型文件，不能直接二次调用该接口。<br>
	必须先删除当前的 IEC61850 对象（通过 #IEC61850_Free() 删除），再重新创建新的 IEC61850 对象（通过 #IEC61850_Create() 创建），<br>
	再通过该接口为新的 IEC61850 对象指定新的模型文件。

	<b>示例</b>

	配置文件例：<br>
	在client.ini中配置：
	\code
	[IED]
	name=ClientIED					# 为客户端设置设备名
	AP_Count=1						# 表示客户端设置1个接入点
	[AP_0]							# 第一个接入点，AP_加序号，序号从0开始
	name=ap01						# 接入点名称
	ipAddress=192.168.8.1			# 接入点IP
	subnet=255.255.255.0			# 子网掩码
	gateway=192.168.8.2				# 网关地址
	macAddress=00-50-56-C0-00-08	# 接入点MAC地址（如果需要订阅goose或者sv）
	\endcode

	接口调用例：
	\code
	IEC61850_ErrorCode result = S_OK;

	StringList* sclList = StringListMalloc();
	StringListAdd(sclList, "./cms-cid/server1.cid");
	StringListAdd(sclList, "./cms-cid/server2.cid");

	result = IEC61850_LoadServerSCLList(iec61850, sclList);
	if (result != S_OK) {
		printf("   Loading SCL file list has failed: %s (%d)\n", filename, IEC61850_ErrorString(result), result);
	}
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_LoadServerSCLList(IEC61850 client, StringList* sclList);

/*!	\brief	该接口用于客户端通过配置文件(cid中表述子网及装置连接信息的部分)直接连接服务端。
	\details
	协议栈会根据加载的模型文件，来启动对应的服务。<br>
	该接口需要在 IEC61850_Create() 创建完 IEC61850 客户端实例之后调用。<br>
	使用的客户端配置文件，是一个基于 cid 模型文件裁剪的 xml 文件，<br>
	可从一个常规的客户端 cid 模型来提取，<br>
	去掉标准模型文件中的 IED 中的 LD、LN 的模型，以及数据类型模板(DataTypeTemplates)的部分，<br>
	保留客户端、服务端的通信(Communication)信息，以及 IED 与 Communication 的关联关系即可。

	\ingroup	Management

	\param[in]	client	IEC61850 对象。对象角色必须是客户端 IEC61850_CLIENT
	\param[in]	cfg		客户端配置文件路径

	\return		错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	<b>示例</b>

	配置文件例：
	\code
	<SCL xmlns="http://www.iec.ch/61850/2003/SCL" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" release="4" revision="B" version="2007" xsi:schemaLocation="http://www.iec.ch/61850/2003/SCL SCL.xsd">
		<Header id="0" version="0"/>
		<Communication>
			<SubNetwork name="SubNetworkName">
				<ConnectedAP apName="CAP" iedName="ClientIED">
					<Address>
						<P type="OSI-AP-Title">1,1,9999,1</P>
						<P type="OSI-AE-Qualifier">12</P>
						<P type="OSI-PSEL">00000001</P>
						<P type="OSI-SSEL">0001</P>
						<P type="OSI-TSEL">0001</P>
						<P type="IP">192.168.8.1</P>
						<P type="IP-SUBNET">255.255.255.0</P>
						<P type="IP-GATEWAY">192.168.8.2</P>
						<P type="MAC-Address">00-50-56-C0-00-08</P>
					</Address>
				</ConnectedAP>
				<ConnectedAP apName="SAP" iedName="ServerIED">
					<Address>
						<P type="OSI-AP-Title">1,1,9999,1</P>
						<P type="OSI-AE-Qualifier">12</P>
						<P type="OSI-PSEL">00000001</P>
						<P type="OSI-SSEL">0001</P>
						<P type="OSI-TSEL">0001</P>
						<P type="IP">192.168.8.1</P>
						<P type="IP-SUBNET">255.255.255.0</P>
						<P type="IP-GATEWAY">192.168.8.2</P>
						<P type="MAC-Address">00-50-56-C0-00-08</P>
					</Address>
				<SMV cbName="svcb" ldInst="Example">
					<Address>
						<P type="MAC-Address">01-0C-CD-04-00-00</P>
						<P type="APPID">0000</P>
						<P type="VLAN-PRIORITY">4</P>
						<P type="VLAN-ID">000</P>
					</Address>
				</SMV>
				</ConnectedAP>
			</SubNetwork>
		</Communication>
		<IED name="ClientIED">
			<AccessPoint name="CAP">
			</AccessPoint>
		</IED>
		<IED configVersion="1.0" name="ServerIED" type="RTUType">
			<AccessPoint name="SAP">
				<Server timeout="30">
					<Authentication/>
				</Server>
			</AccessPoint>
		</IED>
	</SCL>
	\endcode

	接口调用例：
	\code
	IEC61850_ErrorCode result = S_OK;
	result = IEC61850_ClientConnect(client, "./cms-cid/client-direct.xml");	// 'client' is the IEC61850 instance created by IEC61850_Create()
	if (result != S_OK) {
		printf("Failed to connect to server via config file: %s (%d)", IEC61850_ErrorString(result), result);
	}
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_ClientConnect(IEC61850 client, const char* cfg);

/*!	\brief	该接口用于客户端直接连接服务端。
	\details
	需要在 IEC61850_Create() 完成之后调用。

	\ingroup	Management

	\param[in]		client	IEC61850 对象。对象角色必须是客户端 IEC61850_CLIENT
	\param[in]		params	连接参数
	\param[in]		iedName	装置名称
	\param[in,out]	aaIndex	返回的服务端连接索引(serverIndex)

	\return		错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	<b>示例</b>
	\code
	IEC61850_ErrorCode error = S_OK;
	U32 aaIndex = 0; // serverIndex
	IEC61850_AssociationParameters assocParams = { 0 };
	char* iedName = "exampleIEDName";

	strncpy(assocParams.IPAddress, "192.168.8.1", 16);
	assocParams.port = 8102;

	error = IEC61850_ClientConnectDirect(client, &assocParams, iedName, &aaIndex);
	if (error != S_OK) {
		printf("Failed to connect to server: %s (%d)", IEC61850_ErrorString(error), error);
	}
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_ClientConnectDirect(IEC61850 client, IEC61850_AssociationParameters* params, const char* iedName, U32* aaIndex);

/*!	\brief	该接口用于客户端直接断开连接。
	\details
	需要在 IEC61850_Create()完成之后调用。

	\ingroup	Management

	\param[in]	client	IEC61850 对象。对象角色必须是客户端 IEC61850_CLIENT
	\param[in]	aaIndex	服务端连接的索引(serverIndex)

	\return		错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>
				失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	\remark
	可通过 IEC61850_GetConnectionsList() 接口来查询客户端所连接的服务端的索引。

	\see	IEC61850_GetConnectionsList()

	<b>示例</b>
	\code
	U32 serverIndex = 0;
	IEC61850_ErrorCode error = IEC61850_ClientDisconnectDirect(client, serverIndex);	// 'client' is the IEC61850 instance created by IEC61850_Create()
	if (error != S_OK) {
		printf("Failed to disconnect server: %s (%d)", IEC61850_ErrorString(error), error);
	}
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_ClientDisconnectDirect(IEC61850 client, U32 aaIndex);

/*!	\brief	启动 IEC61850 对象的服务。
	\details
	需要在 IEC61850_Create() 和 IEC61850_LoadSCLFile() 完成之后调用。<br>
	协议栈会根据加载的模型文件，来启动对应的服务。

	\ingroup	Management

	\param[in]	iec61850	IEC61850 对象

	\return		错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	\see IEC61850_Stop()

	<b>示例</b>
	\code
		IEC61850_ErrorCode error = S_OK;

		error = IEC61850_Start(iec61850);
		if (error != S_OK) {
			printf("Can't start server: %s (%d)", IEC61850_ErrorString(error), error);
		}
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_Start(IEC61850 iec61850);

/*!	\brief	停止由 `IEC61850_Start()` 启动的 IEC61850 对象的服务。
	\ingroup	Management

	\param[in]	iec61850	IEC61850 对象

	\return		错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	\see IEC61850_Start()

	<b>示例</b>
	\code
	IEC61850_ErrorCode error = S_OK;
	error = IEC61850_Stop(iec61850);
	if (error != S_OK) {
		printf("Can't stop server: %s (%d)", IEC61850_ErrorString(error), error);
	}
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_Stop(IEC61850 iec61850);

/*!	\brief	该接口用于更新数据属性的值。
	\details
	该接口为服务端使用的接口，仅能由服务端调用，客户端禁止调用。<br>
	<br>
	该接口基于数据属性ID（DAID）来更新数据。<br>
	要更新的数据的 DAID ，由 `daid` 参数指定；要更新的数据值，由 `newValue` 参数指定。<br>
	<br>
	要使用该接口更新数据，服务端的模型中需要为数据属性配置 DAID。

	\ingroup	DataAttributeAccess

	\param[in]	server		IEC61850 对象。<br>对象角色必须是服务端 `IEC61850_SERVER`
	\param[in]	daid		要更新数据的 DAID。<br>
							更新的数据为多个时，应指定为一个包含多个数据属ID的 `IEC61850_DataAttributeID` 数组的首地址，元素数量通过成员 `count` 指定，且应与成员 `newValue` 的数量一致。
	\param[in]	newValue	要更新的数据属性值。<br>
							更新的数据为多个时，应指定为一个包含多个数据属性值的 `IEC61850_DataAttributeData` 数组的首地址，元素数量通过成员 `count` 指定，且应与成员 `daid` 的数量一致。
	\param[in]	count		更新的数据数量。<br>
							需要与实际更新的数据数量匹配，数量应在 1~128 之间。<br>
							更新的数据为单个时，应指定为 1；<br>
							更新的数据为多个时，应指定为对应的元素数量，数量应该与 `daid` 和 `newValue` 中实际的元素数量一致。

	\return	错误码。<br>
			成功则返回 #IEC61850_ERROR_NONE (0)；<br>
			失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	<b>示例</b>

	模型中，数据属性ID（DAID）的建模示例：
	\code
	<LN desc="Neutral current regulator" inst="0" lnClass="ANCR" lnType="ANCR_0" prefix="">
		<DOI desc="Single point status" name="Loc">
			<DAI name="stVal" sAddr="@1.2.3.4.5"/>
		</DOI>
	</LN>
	\endcode
	
	<b>更新单个数据示例代码：</b>
	\code
	IEC61850_DataAttributeID daid = { 1, 2, 3, 4, 5 };	// 准备 DAID
	IEC61850_DataAttributeData data = { 0 };	// 准备数据

	Boolean val = TRUE;	// 定义原始数据
	IEC61850_SetDataBoolean(&data, &val);

	IEC61850_ErrorCode error = IEC61850_ERROR_NONE;
	IEC61850 server = GetMyServerClient();   // 获取 IEC61850 对象
	error = IEC61850_Update(server, &daid, &data, 1);	// 通过 DAID 更新数据
	if (error != IEC61850_ERROR_NONE) {
		// 更新失败
	} else {
		// 更新成功
	}
	\endcode

	<b>更新多个数据示例代码：</b>
	\code
	IEC61850_DataAttributeID daid[3] = { {1, 2, 3, 4, 0}, {1, 2, 3, 4, 1}, {1, 2, 3, 4, 2} };
	IEC61850_DataAttributeData val[3] = { 0 };

	Float32 f = (Float32)123.456;
	IEC61850_SetDataFloat32(&val[0], &f);

	tIEC61850Quality q = IEC61850_QUALITY_GOOD;
	IEC61850_SetDataQuality(&val[1], &q); 
	 
	IEC61850_TimeStamp t = { 0 };
	IEC61850_GetTime(NULL, &t);
	IEC61850_SetDataTimestamp(&val[2], &t);

	IEC61850_ErrorCode error = IEC61850_ERROR_NONE;
	IEC61850 server = GetMyServerClient();
	error = IEC61850_Update(server, daid, val, 3);
	if (error != IEC61850_ERROR_NONE) {
		// 更新失败
	} else {
		// 更新成功
	}
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_Update(IEC61850 server, IEC61850_DataAttributeID* daid, const IEC61850_DataAttributeData* newValue, unsigned int count);

/*!	\brief	该接口用于实现对数据属性值的更新
	\details
	该接口为服务端使用的接口，仅能由服务端调用，客户端禁止调用。<br>
	该接口的功能与 `IEC61850_Update()` 接口相同，区别为，该接口是基于短地址（sAddr）来更新数据的。<br>
	要更新的数据的 sAddr ，由 `sAddrList` 参数指定；要更新的数据值，由 `newValue` 参数指定。<br>
	<br>
	要使用该接口更新数据，服务端的模型中需要为数据属性配置 sAddr。

	\ingroup	DataAttributeAccess

	\param[in]	server		IEC61850 对象。<br>对象角色必须是服务端 `IEC61850_SERVER`
	\param[in]	sAddrList	要更新数据的 sAddr。<br>
							应指定为包含一个或多个短地址的 `char*` 数组的首地址，元素数量通过成员 `count` 指定，且应与成员 `newValue` 的数量一致。
	\param[in]	newValue	要更新的数据属性值。<br>
							更新的数据为多个时，应指定为一个包含多个数据属性值的 `IEC61850_DataAttributeData` 数组的首地址，元素数量通过成员 `count` 指定，且应与成员 `sAddrList` 的数量一致。
	\param[in]	count		更新的数据数量。<br>
							需要与实际更新的数据数量匹配，数量应在 1~128 之间。<br>
							更新的数据为单个时，应指定为 1；<br>
							更新的数据为多个时，应指定为对应的元素数量，数量应该与 `sAddrList` 和 `newValue` 中实际的元素数量一致。

	\return	错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	\attention
	该接口不支持更新数组数据和数组元素数据。

	<b>示例</b>

	模型中短地址（sAddr）的建模示例：
	\code
	<LN desc="Measurement" inst="0" lnClass="MMXU" lnType="MMXU_0" prefix="">
		<DOI desc="" name="A">
			<SDI name="phsA">
				<SDI name="cVal">
					<SDI name="mag">
						<DAI name="i" sAddr="aaa"/>
					</SDI>
				</SDI>
				<DAI name="q" sAddr="bbb"/>
				<DAI name="t" sAddr="ccc"/>
			</SDI>
		</DOI>
	</LN>
	\endcode

	接口代码调用示例：
	\code
	char* sAddr[3] = { "aaa", "bbb",  "ccc" };
	IEC61850_DataAttributeData val[3] = { 0 };
	S32 intValue = 123;
	IEC61850_SetDataInt32(&val[0], &intValue);

	tIEC61850Quality q = IEC61850_QUALITY_INVALID | IEC61850_QUALITY_OVERFLOW;
	IEC61850_SetDataQuality(&val[1], &q);

	IEC61850_TimeStamp t = { 0 };
	IEC61850_GetTime(NULL, &t);
	IEC61850_SetDataTimestamp(&val[2], &t);
	IEC61850_ErrorCode result = IEC61850_UpdateWithShortAddr(GetMyServerClient(), sAddr, val, 3);
	if (result == IEC61850_ERROR_NONE) {
		// 更新成功
	} else {
		// 更新失败
	}
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_UpdateWithShortAddr(IEC61850 server, char** sAddrList, const IEC61850_DataAttributeData* newValue, unsigned int count);

/*!	\brief	该接口用于实现对数据属性值的更新。
	\details
	该接口为服务端使用的接口，仅能由服务端调用，客户端禁止调用。<br>
	<br>
	该接口的功能与 `IEC61850_Update()` 接口相同，区别为，该接口是基于引用（reference）来更新数据的。<br>
	要更新的数据的引用，由 `reference` 参数指定；
	要更新的数据值，由 `newValue` 参数指定。

	\remark
	该接口每次仅能更新一个数据点，且该接口不支持更新数组数据和数组元素数据。

	\ingroup	DataAttributeAccess

	\param[in]	server		IEC61850 对象。<br>对象角色必须是服务端 `IEC61850_SERVER`
	\param[in]	reference	要更新数据的引用。<br>例如：`LDName/LNName.DOName.DAName`
	\param[in]	newValue	要更新的数据属性值。<br>应指定为一个 `IEC61850_DataAttributeData` 数据的地址。

	\return		错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	<b>示例</b>
	\code
	char* reference[3] = { "LDName/GGIO0.AnIn1.mag.f", "LDName/GGIO0.AnIn1.q", "LDName/GGIO0.AnIn1.t" };
	IEC61850_DataAttributeData val[3] = { 0 };
	Float32 f = (Float32)123.456;
	IEC61850_SetDataFloat32(&val[0], &f);

	tIEC61850Quality q = IEC61850_QUALITY_QUESTIONABLE | IEC61850_QUALITY_OLDDATA;
	IEC61850_SetDataQuality(&val[1], &q);

	IEC61850_TimeStamp t = { 0 };
	IEC61850_GetTime(NULL, &t);
	IEC61850_SetDataTimestamp(&val[2], &t);

	IEC61850_ErrorCode eErrorCode = IEC61850_ERROR_NONE;
	IEC61850 server = GetMyServerClient();
	for (int i = 0; i < 3; i++) {
		eErrorCode = IEC61850_UpdateWithReference(server, reference[i], &val[i]);
		if (eErrorCode == IEC61850_ERROR_NONE) {
			// 更新成功
		} else {
			// 更新失败
		}
	}
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_UpdateWithReference(IEC61850 server, char* reference, const IEC61850_DataAttributeData* newValue);

/*!	\brief	该接口用于更新数据属性的值，并同时更新其对应 q 和 t 的值。
	\details
	该接口为可同时更新 q、t 的数据更新接口，<br>
	前提是，被更新的数据属性（例如 stVal）所属的数据对象中，存在 q、t 数据属性，<br>
	并且 q、t 两个数据属性在模型文件中的定义必须相邻，且必须为 q 在前、t 在后的顺序。<br>
	<br>
	该接口可基于任意类型的的数据映射信息（数据属性ID（DAID）/短地址（sAddr）/引用（Reference））来更新数据，<br>
	数据映射信息由 `dataMap` 参数指定，其对应的数据映射模式的类别，由 `mapMode` 参数指定，<br>
	要更新的数据属性的值，及其对应的 q、t 属性的值，由 `newValue` 参数指定。<br>
	<br>
	若要通过 DAID/sAddr 来更新数据，则服务端的模型中需要为数据属性配置 DAID/sAddr。<br>
	（只需为主要更新的数据属性（例如 stVal）配置数据映射信息，q、t 两个数据属性无需配置数据映射信息）<br>
	<br>
	该接口为服务端使用的接口，仅能由服务端调用，客户端禁止调用。

	\ingroup	DataAttributeAccess

	\param[in]	server		IEC61850 对象。对象角色必须是服务端 IEC61850_SERVER
	\param[in]	dataMap		要更新的数据属性的 数据映射信息，例如数据属性ID（DAID）、短地址（sAddr）、引用（Reference）。<br>
							应指定为包含至少一个 `IEC61850_DataAttributeID` 或 `char*` 元素的数组的首地址，<br>
							（必须是同一种类型的数据映射信息，不能是多种类型的混合）<br>
							更新的数据数量由 `count` 参数指定，且应与参数 newValue 包含的数据值数量一致。
	\param[in]	newValue	要更新的数据属性值。<br>
							应指定为包含至少一个 `IEC61850_DataAttributeDataQT` 元素的数组的首地址，<br>
							更新的数据数量由 `count` 参数指定，且应与参数 dataMap 包含的数据映射信息数量一致。
	\param[in]	count		更新的数据数量。<br>
	 						需要与实际更新的数据数量匹配，即，需要与 newValue 和 dataMap 参数中包含的元素数量一致。<br>
							数量应在 1~128 之间。<br>
							更新的数据为单个时，应指定为 1；<br>
							更新的数据为多个时，应指定为对应的元素数量。
	\param[in]	mapMode		与 dataMap 参数的类型相对应的数据映射模式类别<br>
							dataMap 参数为数据属性ID（DAID）时，需指定为 #IEC61850_MAP_MODE_DAID <br>
							dataMap 参数为短地址（sAddr）时，需指定为 #IEC61850_MAP_MODE_SADDR <br>
							dataMap 参数为引用（Reference）时，需指定为 #IEC61850_MAP_MODE_REFERENCE
	
	\return	错误码。<br>
			成功则返回 #IEC61850_ERROR_NONE (0)；<br>
			失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	<b>示例</b>

	模型中，数据属性ID（DAID）的建模示例：
	\code
	<LN desc="Measurement" inst="0" lnClass="MMXU" lnType="MMXU_0" prefix="">
		<DOI desc="Phase to ground related measurement values of a three phase Star" name="A">
			<SDI desc="Complex measured value" name="phsA">
				<SDI name="cVal">
					<SDI name="mag">
						<DAI name="i" sAddr="@3.0.0.0.0"/>
					</SDI>
				</SDI>
			</SDI>
			<SDI desc="Complex measured value" name="phsB">
				<SDI name="cVal">
					<SDI name="mag">
						<DAI name="i" sAddr="@4.0.0.0.0"/>
					</SDI>
				</SDI>
			</SDI>
			<SDI desc="Complex measured value" name="phsC">
				<SDI name="cVal">
					<SDI name="mag">
						<DAI name="i" sAddr="@5.0.0.0.0"/>
					</SDI>
				</SDI>
			</SDI>
		</DOI>
	</LN>
	\endcode

	模板部分必须包含q、t，如下：
	\code
	<LNodeType id="MMXU_0" lnClass="MMXU">
		<DO desc="Phase to ground related measurement values of a three phase Star" name="A" type="WYE_0"/>
	</LNodeType>
	<DOType cdc="WYE" desc="Phase to ground related measurement values of a three phase Star" id="WYE_0">
		<SDO desc="Complex measured value" name="phsA" type="CMV_0"/>
		<SDO desc="Complex measured value" name="phsB" type="CMV_1"/>
		<SDO desc="Complex measured value" name="phsC" type="CMV_2"/>
	</DOType>
	<DOType cdc="CMV" desc="Complex measured value" id="CMV_0">
		<DA bType="Struct" dchg="true" dupd="true" fc="MX" name="cVal" type="cVal_0"/>
		<DA bType="Quality" fc="MX" name="q" qchg="true"/>
		<DA bType="Timestamp" fc="MX" name="t"/>
	</DOType>
	<DAType id="cVal_0">
		<BDA bType="Struct" name="mag" type="mag_0"/>
	</DAType>
	<DAType id="mag_0">
		<BDA bType="INT32" name="i"/>
	</DAType>
	\endcode

	更新数据示例代码：
	\code
	IEC61850_ErrorCode result = S_OK;
	IEC61850 server = GetMyServerClient();
	IEC61850_DataMapMode mapMode = IEC61850_MAP_MODE_DAID;
	IEC61850_DataAttributeID daid[3] = {
		{3, 0, 0, 0, 0},
		{4, 0, 0, 0, 0},
		{5, 0, 0, 0, 0}
	};
	IEC61850_DataAttributeDataQT newValue[3] = { 0 };

	S32 value1 = 123;
	tIEC61850Quality q1 = IEC61850_QUALITY_FAILURE;
	IEC61850_TimeStamp t1 = { 0 };

	S32 value2 = 456;
	tIEC61850Quality q2 = IEC61850_QUALITY_OVERFLOW;
	IEC61850_TimeStamp t2 = { 0 };

	S32 value3 = 789;
	tIEC61850Quality q3 = IEC61850_QUALITY_OUTOFRANGE;
	IEC61850_TimeStamp t3 = { 0 };

	IEC61850_GetTime(NULL, &t1);
	IEC61850_GetTime(NULL, &t2);
	IEC61850_GetTime(NULL, &t3);

	newValue[0].dataVal.bitLength = sizeof(S32) * 8;
	newValue[0].dataVal.type = IEC61850_DATATYPE_INT32;
	newValue[0].dataVal.pvData = &value1;
	newValue[0].q = &q1;
	newValue[0].t = &t1;

	newValue[1].dataVal.bitLength = sizeof(S32) * 8;
	newValue[1].dataVal.type = IEC61850_DATATYPE_INT32;
	newValue[1].dataVal.pvData = &value2;
	newValue[1].q = &q2;
	newValue[1].t = &t2;

	newValue[2].dataVal.bitLength = sizeof(S32) * 8;
	newValue[2].dataVal.type = IEC61850_DATATYPE_INT32;
	newValue[2].dataVal.pvData = &value3;
	newValue[2].q = &q3;
	newValue[2].t = &t3;

	result = IEC61850_UpdateWithQT(server, daid, newValue, 3, mapMode);
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_UpdateWithQT(IEC61850 server, void* dataMap, IEC61850_DataAttributeDataQT* newValue, unsigned int count, IEC61850_DataMapMode mapMode);

/*!	\brief	读数据。（基于DAID）
	\details
	该接口基于 DAID 来读数据属性的值。<br>
	该接口为客户端使用的接口，服务端禁止调用。<br>
	若 `daid` 参数所指定的 DAID 不存在，将读取失败，不会返回数据值。

	\ingroup	DataAttributeAccess

	\param[in]		client			IEC61850 对象。<br>对象角色必须是客户端 `IEC61850_CLIENT` 
	\param[in]		daid			要读的数据的 DAID
	\param[in,out]	returnedValue	读到的数据值

	\return		错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	<b>示例</b>
	\code
	IEC61850_ErrorCode error = S_OK;
	IEC61850_DataAttributeID daid = { 1, 2, 3, 4, 5 };
	IEC61850_DataAttributeData data = { 0 };
	U32 val = 0;

	data.type = IEC61850_DATATYPE_INT32U;
	data.bitLength = sizeof(val) * 8;
	data.arrayIndex = 0;
	data.pvData = &val;

	error = IEC61850_Read(client, &daid, &data);
	if (error != S_OK) {
		printf("Read failed: %s (%d)", IEC61850_ErrorString(error), error);
	} else {
		printf("Data value = %u", val);
	}
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_Read(IEC61850 client, IEC61850_DataAttributeID* daid, IEC61850_DataAttributeData* returnedValue);

/*!	\brief	写数据。（基于DAID）
	\details
	该接口基于 DAID 来写数据属性的值。<br>
	该接口为客户端使用的接口，服务端禁止调用。<br>
	若 `daid` 参数指定的 DAID 不存在，数据将写入失败。<br>
	同时，`newValue` 参数指定的数据值，应包含正确的数据类型、数据长度，以及取值范围内的有效数据值。

	\ingroup	DataAttributeAccess

	\param[in]	client		IEC61850 对象。<br>对象角色必须是客户端 `IEC61850_CLIENT`
	\param[in]	daid		要写的数据对应的 DAID
	\param[in]	newValue	要写的数据值

	\return		错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	\remark
	数据是否是客户端可写的，通常受到数据对应功能约束（FC）的限制。
	例如，最常见的 FC=ST 的状态量数据，以及 FC=MX 的模拟量数据，就是客户端不可以写的，只能由服务端更新。
	客户端一般仅可以写 FC=SP、FC=SV 的数据，以及部分非特定性质的 FC=CF、FC=DC 的数据。
	关于功能约束的可读写性质，可以参照 IEC61850-7-2:2010（DL/T 860.72-2013）的 12.3.3.2 章节的 表20。

	<b>示例</b>
	\code
	IEC61850_DataAttributeData data = { 0 };
	IEC61850_DataAttributeID daid = {1, 4, 1, 0, 0};
	Boolean val = TRUE;
	IEC61850_SetDataBoolean(&data, &val);

	IEC61850_ErrorCode error = IEC61850_Write(client, &daid, &data);
	if (error != S_OK) {
		printf("Write failed: %s (%d)", IEC61850_ErrorString(error), error);
	}
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_Write(IEC61850 client, IEC61850_DataAttributeID* daid, const IEC61850_DataAttributeData* newValue);

/*!	\brief	读数据。（基于引用和功能约束)
	\details
	该接口基于数据属性的引用和功能约束，来读取数据的值。<br>
	该接口为客户端使用的接口，服务端禁止调用。

	\ingroup	Support

	\param[in]		client			IEC61850 对象。<br>对象角色必须是客户端 `IEC61850_CLIENT`
	\param[in]		serverIndex		服务端的索引号
	\param[in]		fcdas			请求读的数据信息。<br>
									应为一个 `FCDA` 数组的首地址，<br>
									数组元素的数量应与 `count` 参数值一致，<br>
									每个元素依次对应请求读取的数据，其中包含请求读取数据的引用和功能约束。
	\param[in,out]	datasToBeRead	读到的数据值。<br>
									该参数用于接收读每个数据响应的数据值。<br>
									该参数应按照 `fcdas` 参数中请求读取的数据数量提前构建，<br>
									应指定为一个 `IEC61850_DataAttributeData` 数组的首地址，<br>
									数组元素的数量应与请求读取的数据数量（`count` 参数值）一致，<br>
									每个元素用于保存对应读取到的 `fcdas` 中各个数据的数据值。
	\param[in,out]	serviceError	响应的 ServiceError。<br>
									该参数用于接收读每个数据对应响应的 ServiceError。<br>
									该参数应按照 `fcdas` 参数中请求读取的数据数量提前构建，应指定为一个 #eServiceError 数组的首地址，<br>
									数组元素的数量应与请求读取的数据数量（`count` 参数值）一致，<br>
									每个元素依次对应读取 `fcdas` 中各个数据所响应的 ServiceError。<br>
									读成功的数据对应响应 `SERVICE_ERROR_NO_ERROR` (0) ；<br>
									读失败的数据对应响应非 0 值的 #eServiceError 。
	\param[in]		count			读的数据数量。<br>
									用于指定 `fcdas`、`datasToBeRead`、`serviceError` 三个参数中包含的数据元素数量，<br>
									三者的数量必须一致，必须同为 `count` 指定的数量。

	\return		错误码。<br>成功则返回  #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	\remark
	特定功能的数据（例如各类控制块的属性、定值等），应按照特定 ACSI（例如 GetBRCBValues、GetEditSGValue 等）的方法来读。

	<b>示例</b>
	\code
	FCDA data[3] = { 0 };
	IEC61850_DataAttributeData datasToBeRead[3] = { 0 };
	eServiceError serviceErr[3] = { 0 };

	data[0].reference = "LDName/MMXU0.A.phsA";
	data[0].fc = "MX";
	data[1].reference = "LDName/MMXU0.A.phsB.cVal";
	data[1].fc = "MX";
	data[2].reference = "LDName/MMXU0.A.phsC.cVal.mag.i";
	data[2].fc = "MX";

	IEC61850_ErrorCode result = IEC61850_ReadDirect(GetMyServerClient(), 0, data, datasToBeRead, serviceErr, 3);
	if (result == IEC61850_ERROR_NONE) {
		printf("Read success\n");
	} else {
		printf("Read failed\n");
	}
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_ReadDirect(IEC61850 client, unsigned int serverIndex, FCDA* fcdas, IEC61850_DataAttributeData* datasToBeRead, eServiceError* serviceError, unsigned int count);

/*!	\brief	写数据。（基于引用和功能约束)
	\details
	该接口基于数据属性的引用和功能约束，来写数据的值。<br>
	该接口为客户端使用的接口，服务端禁止调用。<br>
	调用该接口时，应已知所写数据的信息（类型、长度等），并正确地构建要写入的数据值参数 `dataToBeWrite`。

	\ingroup	Support

	\param[in]		client			IEC61850 对象。<br>对象角色必须是客户端 `IEC61850_CLIENT` 
	\param[in]		serverIndex		服务端的索引号
	\param[in]		dataRefFC		要写的数据信息。<br>
									应为一个 `FCDA` 数组的首地址，<br>
									数组元素的数量应与 `count` 参数值一致，<br>
									每个元素依次对应一个请求写的数据的引用和功能约束。
	\param[in]		dataToBeWrite	要写的数据值。<br>
									应为一个 `IEC61850_DataAttributeData` 数组的首地址，<br>
									数组元素的数量应与 `dataRefFC` 参数中请求写的数据数量（`count` 参数值）一致，<br>
									每个元素依次对应 `dataRefFC` 中每个要写的数据的值。
	\param[in,out]	serviceError	响应的 ServiceError。<br>
									应为一个 #eServiceError 数组的首地址，<br>
									数组元素的数量应与 `dataRefFC` 参数中请求写的数据数量（`count` 参数值）一致，<br>
									每个元素依次对应写 `dataRefFC` 所指定的各个数据所响应的 ServiceError。<br>
									写成功的数据对应响应 `SERVICE_ERROR_NO_ERROR` (0) ；<br>
									写失败的数据对应响其他非 0 值的 #eServiceError 。
	\param[in]		count			写的数据数量。<br>
									用于指定 `dataRefFC`、`dataToBeWrite`、`serviceError` 三个参数中包含的数据数量，<br>
									三者的数量必须一致，必须同为 `count` 指定的数量。

	\return		错误码。<br>成功则返回  #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	\remark
	数据是否是客户端可写的，通常受到数据对应功能约束（FC）的限制。<br>
	例如，最常见的 FC=ST 的状态量数据，以及 FC=MX 的模拟量数据，就是客户端不可以写的，只能由服务端更新。<br>
	客户端一般仅可以写 FC=SP、FC=SV 的数据，以及部分非特定性质的 FC=CF、FC=DC 的数据。<br>
	<br>
	关于功能约束的可读写性质，可以参照 IEC61850-7-2:2010（DL/T 860.72-2013）的 12.3.3.2 章节的 表20。<br>
	<br>
	特定功能的数据（例如各类控制块的属性、定值等），应按照特定 ACSI（例如 SetBRCBValues、SetEditSGValue 等）的方法来写。

	<b>示例</b>
	\code
	FCDA data[3] = { 0 };
	IEC61850_DataAttributeData values[3] = { 0 };
	eServiceError serviceErr[3] = { 0 };

	data[0].reference = "LDName/GGIO0.NumSubIntv.setVal";
	data[0].fc = "SP";
	data[1].reference = "LDName/GGIO0.NumSubIntv.minVal";
	data[1].fc = "CF";
	data[2].reference = "LDName/GGIO0.NumSubIntv.maxVal";
	data[2].fc = "CF";

	S32 setVal = 2, minVal = 1, maxVal = 3;

	IEC61850_SetDataInt32(&values[0], &setVal);
	IEC61850_SetDataInt32(&values[1], &minVal);
	IEC61850_SetDataInt32(&values[2], &maxVal);

	IEC61850_ErrorCode result = IEC61850_WriteDirect(GetMyServerClient(), 0, data, values, serviceErr, 3);
	if (result == IEC61850_ERROR_NONE) {
		printf("Write success\n");
	} else {
		printf("Write failed\n");
	}
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_WriteDirect(IEC61850 client, unsigned int serverIndex, FCDA* dataRefFC, IEC61850_DataAttributeData* dataToBeWrite, eServiceError* serviceError, unsigned int count);

/*!	\brief	该接口用于返回错误码 `IEC61850_ErrorCode` 枚举值所对应含义的字符串。
	\ingroup	Support

	\param[in]	code	错误码的枚举值 #IEC61850_ErrorCode

	\return	错误码含义的字符串
*/
PIS10_API const char* IEC61850_ErrorString(IEC61850_ErrorCode code);

/*!	\brief	该接口用于获取 YX-PIS 协议栈的版本号。
	\details
	该接口无入参，返回值是协议栈版本号宏值 `YX_PIS_VERSION` 对应的字符串，例如 `VX.X.X.X` 。

	\ingroup	Support

	\return		YX-PIS 协议栈的版本号
*/
PIS10_API const char* IEC61850_GetLibraryVersion();

/*!	\brief	该接口可以获取 YX-PIS 协议栈库的创建时间。
	\details
	该接口无入参，返回值是一个代表时间的字符串，其内容格式与协议栈的运行环境有关。例如 `Feb  3 2020 12:34:56`。

	\ingroup	Support

	\return		YX-PIS 协议栈库的创建时间。
*/
PIS10_API const char* IEC61850_GetLibraryBuildTime();

/*!	\brief	该接口用于设置时间品质。
	\details
	该接口各个参数的意义，同 `IEC61850_GetTimeQuality()` 接口。<br>
	前三个参数 `leapSecondKnown`、`clockFailure`、`clockNotSynchronized` 依次代表时间品质的 0、1、2 三个 bit 位。<br>
	若这三个参数传入非 0 值，则时间品质对应的标志位将被置为 1，反之则置为 0；<br>
	第四个参数 `timeAccuracyOfFractionsOfSecond` 为时间品质第 3~7 bit 位所代表的时间精确度。<br>
	若该参数传入 0~24 之间（包含 0 和 24）的值，则时间精度将被设置为对应的值；<br>
	若该参数传入小于 0 的值，则时间精确度将被设置为 "未规定"；<br>
	该参数传入其他值将视为参数无效。

	\ingroup	Time

	\param[in]	leapSecondKnown					闰秒已知（LeapSecondsKnown）
	\param[in]	clockFailure					时钟故障（ClockFailure）
	\param[in]	clockNotSynchronized			时钟未同步（ClockNotSynchronized）
	\param[in]	timeAccuracyOfFractionsOfSecond	"秒的小数" 的时间精确度（TimeAccuracy）

	\return		错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	\attention
	该接口设置的时间品质是全局的，将被应用于 `IEC61850_GetTime()` 、`IEC61850_GetIEC61850TimeFromDate()` 等接口所获取的时间中。

	\see	IEC61850_GetTimeQuality()

	<b>示例</b>
	\code
	IEC61850_ErrorCode error = S_OK;
	error = IEC61850_SetTimeQuality(1, 0, 1, -1);
	if (error != S_OK) {
		printf("IEC61850_SetTimeQuality failed: %s", IEC61850_ErrorString(error));
	}
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_SetTimeQuality(char leapSecondKnown, char clockFailure, char clockNotSynchronized, int timeAccuracyOfFractionsOfSecond);

/*!	\brief	该接口用于获取时间品质。
	\details

	时间品质是一个 8 位的位串（BIT STRING）数据。<br>
	（每个 bit 位的意义，可参照 `struct IEC61850_TimeStamp` 的 `时间品质` 的说明）<br>
	<br>
	该接口将时间品质信息拆分为了以一系列值，以不同的参数传出。<br>
	第一个参数 `leapSecondKnown` 将传出时间品质 bit 位 0 的 `闰秒已知`。如果闰秒已知，则为非 0 值，否则为 0 值；<br>
	第二个参数 `clockFailure` 将传出时间品质 bit 位 1 的 `时钟故障`。若时钟故障，则为非 0 值，否则为 0 值；<br>
	第三个参数 `clockNotSynchronized` 将传出时间品质 bit 位 2 `时钟未同步`。若时钟未同步，则为非 0 值，否则为 0 值；<br>
	第四个参数 `timeAccuracyOfFractionsOfSecond` 将传出时间品质 bit 位 3~7 的 "时间精确度"。<br>
	若该值在 0~24 之间（包含 0 和 24），则时间精确度为数值对应的意义；若该值为小于 0 的负值，则代表时间精确度为 `未规定`。

	\ingroup	Time

	\param[in,out]	leapSecondKnown					闰秒已知（LeapSecondsKnown）
	\param[in,out]	clockFailure					时钟故障（ClockFailure）
	\param[in,out]	clockNotSynchronized			时钟未同步（ClockNotSynchronized）
	\param[in,out]	timeAccuracyOfFractionsOfSecond	"秒的小数" 的时间精确度（TimeAccuracy）
	
	\return	错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	\see	IEC61850_SetTimeQuality()

	<b>示例</b>
	\code
	char leapSecondKnown = 0;
	char clockFailure = 0;
	IEC61850_ErrorCode error = S_OK;
	error = IEC61850_GetTimeQuality(&leapSecondKnown, &clockFailure, NULL, NULL);
	if (error != S_OK) {
		printf("IEC61850_GetTimeQuality failed: %s", IEC61850_ErrorString(error));
	} else {
		printf(" LeapSecondKnown: [%s]\n", (Boolean)leapSecondKnown ? "TRUE" : "FALSE");
		printf(" ClockFailure:    [%s]\n", (Boolean)clockFailure ? "TRUE" : "FALSE");
	}
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_GetTimeQuality(char* leapSecondKnown, char* clockFailure, char* clockNotSynchronized, int* timeAccuracyOfFractionsOfSecond);

/*!	\brief	该接口用于获取当前的系统时间对应的 IEC61850 时间戳。
	\details
	获取的时间戳，将被写入由 `currentTime` 参数指定的 `IEC61850_TimeStamp` 数据中。<br>
	YX-PIS 协议栈内部也会使用 `IEC61850_GetTime()` 来获取时间。<br>
	通过 `IEC61850_SetTimeQuality()` 接口设置的时间品质，会应用到该接口传出的时间戳中。<br>
	<br>
	若用户指定了 `IEC61850_TimeStampCallback` 回调函数，则 `currentTime` 参数将返回由 `IEC61850_TimeStampCallback` 回调函数提供的时间。

	\ingroup	Time

	\param[in]		iec61850	IEC61850 对象，该参数传 NULL 即可。
	\param[in,out]	currentTime	返回的当前时间

	\return	错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	<b>示例</b>
	\code
	IEC61850_TimeStamp time = { 0 };
	IEC61850_GetTime(NULL, &time);
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_GetTime(IEC61850 iec61850, IEC61850_TimeStamp* currentTime);

/*!	\brief	该接口用于设置系统时间，可用于实现对装置系统时钟的对时。
	\details
	该接口通过 IEC61850 时间戳 `IEC61850_TimeStamp` 来指定设置的时间，<br>
	且仅会设置时间（使用 `IEC61850_TimeStamp` 中 秒的整数 和 秒的小数 的数据来设置时间），不会设置时间品质。

	\ingroup	Time

	\param[in]	time	设定的时间

	\return		错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	\attention
	由于时间同步与对时不属于 IEC61850 的实现范畴，<br>
	该接口目前仅在极个别类型的嵌入式系统(例如 BECK)环境下可用，其他系统环境下均不可用。

	<b>示例</b>
	\code
	IEC61850_TimeStamp time = { 0 };
	time.seconds = 455896518;
	time.fractionsOfSecond = 0;
	if (IEC61850_SetTime(&time) != S_OK) {
		printf("Set Time failed");
	}
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_SetTime(IEC61850_TimeStamp* time);


/*!	\brief	该接口用于为 IEC61850 对象指定自定义的用户数据。
	\details
	指定的自定义用户数据，可在该 IEC61850 对象的回调函数被调用时，通过回调函数的首个参数 `userData` 来访问使用。

	\ingroup	Support

	\param[in]	iec61850	IEC61850 对象。用于指定 IEC61850_Create() 创建的 IEC61850 对象
	\param[in]	data		用户自定义数据地址。需确保此地址始终有效，建议使用全局静态数据，或堆创建（calloc/malloc）的数据。

	\return		错误码。设置成功则返回 #IEC61850_ERROR_NONE (0)，设置失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	\attention
	自定义用户数据的生命周期不由协议栈维护，不会被 `IEC61850_Free()` 释放，需要自行管理其生命周期。

	<b>示例</b>
	\code
	struct CustomUserData {
		int  data;
		char ref[130];
	};
	static struct CustomUserData userData = { 0 };
	IEC61850_ErrorCode error = IEC61850_SetUserData(server, &userData);
	if (error != S_OK) {
		printf("set user data failed: %s", IEC61850_ErrorString(error));
	}
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_SetUserData(IEC61850 iec61850, void* data);


/*!	\brief	该接口用于获取指定 DAID 所对应数据属性的数据类型。
	\ingroup	DataAttributeAccess

	\param[in]	iec61850		IEC61850 对象
	\param[in]	daid			数据属性的 DAID
	\param[out]	returnedType	需要使用一个非 NULL 的 IEC61850_DataAttributeData 作为输入

	\return		错误码。<br>设置成功则返回 #IEC61850_ERROR_NONE (0)；<br>设置失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。
*/
PIS10_API IEC61850_ErrorCode IEC61850_GetType(IEC61850 iec61850, IEC61850_DataAttributeID* daid, IEC61850_DataAttributeData* returnedType);

/*!	\brief	该接口用于获取指定 addr短地址 所对应数据属性的数据类型。
	\ingroup	DataAttributeAccess

	\param[in]	iec61850		IEC61850 对象
	\param[in]	addr			数据属性的 短地址
	\param[out]	returnedType	需要使用一个非 NULL 的 IEC61850_DataAttributeData 作为输入

	\return	错误码。<br>设置成功则返回 #IEC61850_ERROR_NONE (0)；<br>设置失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。
*/
PIS10_API IEC61850_ErrorCode IEC61850_GetTypeByShortAddr(IEC61850 iec61850, char* addr, IEC61850_DataAttributeData* returnedType);

/*!	\brief	该接口用于获取指定 reference引用 所对应数据属性的数据类型。
	\ingroup	DataAttributeAccess

	\param[in]	iec61850		IEC61850 对象
	\param[in]	reference		数据属性的 引用
	\param[out]	returnedType	需要使用一个非 NULL 的 IEC61850_DataAttributeData 作为输入

	\return		错误码。<br>设置成功则返回 #IEC61850_ERROR_NONE (0)；<br>设置失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。
*/
PIS10_API IEC61850_ErrorCode IEC61850_GetTypeByReference(IEC61850 iec61850, char* reference, IEC61850_DataAttributeData* returnedType);

/*!	\brief	操作前选择。（基于 sAddr）
	\details
	控制服务接口。用于对指定 sAddr 的控制对象执行操作前选择（Select / SelectWithValue）命令。<br>
	该接口的功和使用方法，与 `IEC61850_ControlSelect()` 接口相同，只是第二个参数由控制对象的 DAID 更换为了 sAddr。<br>
	<br>
	该接口可与同以短地址为参数的控制服务接口 `IEC61850_ControlOperateWithShortAddr()`、`IEC61850_ControlCancelWithShortAddr()` 配合使用。<br>
	该接口为客户端使用的接口，服务端禁止调用。

	\ingroup	Control

	\param[in]	client		IEC61850 对象。<br>对象角色必须是客户端 `IEC61850_CLIENT` 
	\param[in]	sAddr		控制对象 控制值 Oper\.ctlVal 的 sAddr
	\param[in]	selectValue 操作前选择命令的控制值。<br>
							即，带值选择（SelectWithValue）SBOes 控制对象的控制值（ctlVal）；<br>
							对于选择（Select）SBOns 控制对象的场合，应指定为 NULL。
	\param[in]	param		控制参数。<br>
							用于指定控制请求的 同期检查（SynchroCheck）、互锁检查（Interlock\-Check）、测试（Test）属性，以及 "时间激活" 控制的激活时间（operTm）。

	\return	错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。
*/
PIS10_API IEC61850_ErrorCode IEC61850_ControlSelectWithShortAddr(IEC61850 client, char* sAddr, IEC61850_DataAttributeData* selectValue, IEC61850_ControlParameters* param);

/*!	\brief	操作。（基于 sAddr）
	\details
	控制服务接口。用于对指定 sAddr 的控制对象执行操作（Operate / TimeActivatedOperate）命令。<br>
	该接口的功和使用方法，与 `IEC61850_ControlOperate()` 接口相同，只是第二个参数由控制对象的 DAID 更换为了 sAddr。<br>
	该接口可与同以短地址为参数的控制服务接口 `IEC61850_ControlSelectWithShortAddr()`、`IEC61850_ControlCancelWithShortAddr()` 配合使用。<br>
	该接口为客户端使用的接口，服务端禁止调用。

	\ingroup	Control

	\param[in]	client			IEC61850 对象。<br>对象角色必须是客户端 `IEC61850_CLIENT`
	\param[in]	sAddr			控制对象 控制值 Oper\.ctlVal 的 sAddr
	\param[in]	operateValue	操作命令的控制值<br>操作 SBOes 控制对象时，需要与带值选择（SelectWithVal）命令的控制值一致。
	\param[in]	param			控制参数。<br>用于指定控制请求的 同期检查（SynchroCheck）、互锁检查（Interlock\-Check）、测试（Test）属性，以及时间激活控制的操作时间（operTm）。<br>操作 SBOns / SBOes 控制对象时，需要与操作前选择（Select / SelectWithVal）命令的控制参数一致。 

	\return	错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。
*/
PIS10_API IEC61850_ErrorCode IEC61850_ControlOperateWithShortAddr(IEC61850 client, char* sAddr, IEC61850_DataAttributeData* operateValue, IEC61850_ControlParameters* param);

/*!	\brief	取消。（基于 sAddr）
	\details
	控制服务接口。用于对指定 sAddr 的控制对象执行取消（Cancel）命令。<br>
	该接口的功和使用方法，与 `IEC61850_ControlCancel()` 接口相同，只是第二个参数由控制对象的 DAID 更换为了 sAddr。

	该接口可与同以短地址为参数的控制服务接口 `IEC61850_ControlSelectWithShortAddr()`、`IEC61850_ControlOperateWithShortAddr()` 配合使用。
	该接口为客户端使用的接口，服务端禁止调用。

	\ingroup	Control

	\param[in]	client 		IEC61850 对象。<br>对象角色必须是客户端 `IEC61850_CLIENT`
	\param[in]	sAddr 		控制对象 控制值 Oper\.ctlVal 的 sAddr
	\param[in]	cancelValue 取消命令的控制值。<br>需要与要被取消的控制命令（SelectWithVal / TimeActivatedOperate）的控制值一致。<br>取消对 SBOns 控制对象的操作前选择（Select）时，应指定为 NULL。
	\param[in]	param		控制参数。<br>用于指定控制请求的 同期检查（SynchroCheck）、互锁检查（Interlock\-Check）、测试（Test）属性，以及时间激活控制的操作时间（operTm）。<br>需要与要被取消的控制命令（Select / SelectWithVal / TimeActivatedOperate）的控制参数一致。

	\return	错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。
*/
PIS10_API IEC61850_ErrorCode IEC61850_ControlCancelWithShortAddr(IEC61850 client, char* sAddr, IEC61850_DataAttributeData* cancelValue, IEC61850_ControlParameters* param);

/*!	\brief	操作前选择。（基于 DAID）
	\details
	控制服务接口。用于对指定 DAID 的控制对象执行操作前选择命令。<br>
	对应的 ACSI 服务接口为：\"Select\" / \"SelectWithValue\"。<br>
	该接口为客户端使用的接口，服务端禁止调用。<br>
	该接口仅应用于 操作前选择（SBOns / SBOes）的控制对象，不能用于 直接控制（DOns / DOes）的控制对象。<br>
	<br>
	若控制值参数 `selectValue` 为 NULL，则执行适用于 SBOns 控制对象的 选择（Select）命令；<br>
	若控制值参数 `selectValue` 有被设置，则执行适用于 SBOes 控制对象的 带值选择（SelectWithValue）命令。<br>
	<br>
	控制对象被选择成功后，将由未选择（Unselected）状态变为准备就绪（Ready）状态，同时，选择超时计时器将开始计时，<br>
	若超时之前没有对其执行后续的操作命令，其选择状态会因选择超时而被取消，控制对象会复归为未选择（Unselected）状态，再次控制需要重新对其执行操作前选择。<br>
	选择超时的时限，由控制对象的 sboTimeout 数据属性指定。若未明确指定 sboTimeout 时间，则默认为 30 秒。<br>
	<br>
	带有 Oper.operTm 数据属性的控制对象，将被视为时间激活的控制对象。<br>
	若时间激活的控制对象是 SBOes 的，则还需要带有 SBOw.operTm 数据属性。（SBOns 的控制对象仅需要 SBO 数据属性，不需要SBOw.operTm 数据属性）<br>
	带值选择（SelectWithValue）SBOes 的时间激活的控制对象时，需要在 `param` 参数中指定激活控制的操作时间。

	\ingroup	Control

	\param[in]	client		IEC61850 对象。<br>对象角色必须是客户端 `IEC61850_CLIENT`
	\param[in]	daid		控制对象 控制值 Oper\.ctlVal 的 DAID
	\param[in]	selectValue	控制值。<br>即，带值选择（SelectWithValue）SBOes 控制对象的控制值（ctlVal）；<br>对于选择（Select）SBOns 控制对象的场合，应指定为 NULL。
	\param[in]	param		控制参数。<br>用于指定控制请求的 同期检查（SynchroCheck）、互锁检查（Interlock\-Check）、测试（Test）属性，以及时间激活控制的操作时间（operTm）。<br>操作 SBOns / SBOes 控制对象时，需要与操作前选择（Select / SelectWithVal）命令的控制参数一致。

	\return	错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	\see	IEC61850_ControlSelectWithShortAddr(), IEC61850_ControlSelectWithRef()
*/
PIS10_API IEC61850_ErrorCode IEC61850_ControlSelect(IEC61850 client, IEC61850_DataAttributeID* daid, IEC61850_DataAttributeData* selectValue, IEC61850_ControlParameters* param);

/*!	\brief	操作。（基于 DAID）
	\details
	控制服务接口。用于对指定 DAID 的控制对象执行操作命令。<br>
	对应的 ACSI 服务接口为：\"Operate\" / \"TimeActivatedOperate\"。<br>
	该接口为客户端使用的接口，服务端禁止调用。<br>
	<br>
	对于 SBOns / SBOes 的控制对象，应该在调用本接口之前，先调用 `IEC61850_ControlSelect()` 接口对其执行操作前选择。<br>
	选择成功后才可以对其执行操作命令，操作命令需要在选择超时之前执行。<br>
	同时，操作命令附带的控制值和控制参数，也需要与操作前选择命令（Select / SelectWithValue）中的一致。<br>
	<br>
	带有 Oper.operTm 数据属性的控制对象，将被视为时间激活的控制对象，<br>
	对其执行的操作命令将按照 时间激活的操作（TimeActivatedOperate）来处理，<br>
	需要在 `param` 参数中指定激活控制的操作时间。<br>
	若时间激活的控制对象是 SBOes 的，则指定的操作时间也需要与带值选择（SelectWithValue）命令中的一致。

	\ingroup	Control

	\param[in]	client			IEC61850 对象。<br>对象角色必须是客户端 `IEC61850_CLIENT`
	\param[in]	daid			控制对象 控制值 Oper\.ctlVal 的 DAID
	\param[in]	operateValue	操作命令的控制值<br>操作 SBOes 控制对象时，需要与带值选择（SelectWithVal）命令的控制值一致。
	\param[in]	param			控制参数。<br>用于指定控制请求的 同期检查（SynchroCheck）、互锁检查（Interlock\-Check）、测试（Test）属性，以及时间激活控制的操作时间（operTm）。<br>操作 SBOns / SBOes 控制对象时，需要与操作前选择（Select / SelectWithVal）命令的控制参数一致。

	\return	错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	\see	IEC61850_ControlOperateWithShortAddr(), IEC61850_ControlOperateWithRef()
*/
PIS10_API IEC61850_ErrorCode IEC61850_ControlOperate(IEC61850 client, IEC61850_DataAttributeID* daid, IEC61850_DataAttributeData* operateValue, IEC61850_ControlParameters* param);

/*!	\brief	取消。（基于 DAID）
	\details
	控制服务接口。用于对指定 DAID 的控制对象执行取消命令。<br>
	对应的 ACSI 服务接口为：\"Cancel\"。<br>
	该接口为客户端使用的接口，服务端禁止调用。<br>
	<br>
	该接口可用于取消对控制对象的操作前选择（Select / SelectWithValue），以及用于取消尚未到达激活操作时间的时间激活操作（TimeActivatedOperate）。<br>
	取消命令附带的控制值和控制参数，需要与要被取消的控制命令（Select / SelectWithValue / TimeActivatedOperate）的控制值和控制参数一致。

	\ingroup	Control

	\param[in]	client		IEC61850 对象。<br>对象角色必须是客户端 `IEC61850_CLIENT`
	\param[in]	daid		控制对象 控制值 Oper\.ctlVal 的 DAID
	\param[in]	cancelValue	取消命令的控制值。<br>需要与要被取消的控制命令（SelectWithVal / TimeActivatedOperate）的控制值一致。<br>取消对 SBOns 控制对象的操作前选择（Select）时，应指定为 NULL。
	\param[in]	param		控制参数。<br>用于指定控制请求的 同期检查（SynchroCheck）、互锁检查（Interlock\-Check）、测试（Test）属性，以及时间激活控制的操作时间（operTm）。<br>需要与要被取消的控制命令（Select / SelectWithVal / TimeActivatedOperate）的控制参数一致。

	\return	错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	\see	IEC61850_ControlCancelWithShortAddr(), IEC61850_ControlCancelWithRef()
*/
PIS10_API IEC61850_ErrorCode IEC61850_ControlCancel(IEC61850 client, IEC61850_DataAttributeID* daid, IEC61850_DataAttributeData* cancelValue, IEC61850_ControlParameters* param);

/*!	\brief	操作前选择。（基于引用）
	\details
	控制服务接口。用于对指定 DAID 的控制对象执行操作前选择命令。<br>
	对应的 ACSI 服务接口为：\"Select\" / \"SelectWithValue\"。<br>
	该接口为客户端使用的接口，服务端禁止调用。<br>
	该接口仅适用于 操作前选择（SBOns / SBOes）的控制对象，不能用于 直接控制（DOns / DOes）的控制对象。<br>
	<br>
	若控制值参数 `selectValue` 为 NULL，则执行适用于 SBOns 控制对象的 选择（Select）命令；<br>
	若控制值参数 `selectValue` 有被设置，则执行适用于 SBOes 控制对象的 带值选择（SelectWithValue）命令。<br>
	<br>
	控制对象被选择成功后，将由未选择（Unselected）状态变为准备就绪（Ready）状态，<br>
	同时，选择超时计时器将开始计时，<br>
	若超时之前没有对其执行后续的操作命令，其选择状态会因选择超时而被取消，<br>
	控制对象会复归为未选择（Unselected）状态，再次控制需要重新对其执行操作前选择。<br>
	选择超时的时限，由控制对象的 sboTimeout 数据属性指定。若未明确指定 sboTimeout 时间，则默认为 30 秒。<br>
	<br>
	带有 Oper.operTm 数据属性的控制对象，将被视为时间激活的控制对象。<br>
	若时间激活的控制对象是 SBOes 的，则还需要带有 SBOw.operTm 数据属性。（SBOns 的控制对象仅需要 SBO 数据属性，不需要SBOw.operTm 数据属性）<br>
	带值选择（SelectWithValue）SBOes 的时间激活的控制对象时，需要在 `param` 参数中指定激活控制的操作时间。

	\ingroup	Control

	\param[in]	client		IEC61850 对象。<br>对象角色必须是客户端 `IEC61850_CLIENT`
	\param[in]	aaIndex 		连接服务端的连接序号
	\param[in]	ctlRef		控制对象 DO 的引用。例如 `LDName/CSWI0.Pos`
	\param[in]	selectValue	控制值。<br>即，带值选择（SelectWithValue）SBOes 控制对象的控制值（ctlVal）；<br>对于选择（Select）SBOns 控制对象的场合，应指定为 NULL。
	\param[in]	param		控制参数。<br>用于指定控制请求的 同期检查（SynchroCheck）、互锁检查（Interlock\-Check）、测试（Test）属性，以及时间激活控制的操作时间（operTm）。<br>操作 SBOns / SBOes 控制对象时，需要与操作前选择（Select / SelectWithVal）命令的控制参数一致。

	\return	错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	\see	IEC61850_ControlSelect(), IEC61850_ControlSelectWithShortAddr()
*/
PIS10_API IEC61850_ErrorCode IEC61850_ControlSelectWithRef(IEC61850 client, int aaIndex, char* ctlRef, IEC61850_DataAttributeData* selectValue, IEC61850_ControlParameters* param);

/*!	\brief	操作。（基于引用）
	\details
	控制服务接口。用于对指定引用的控制对象执行操作命令。<br>
	对应的 ACSI 服务接口为：\"Operate\" / \"TimeActivatedOperate\"。<br>
	<br>
	对于 SBOns / SBOes 的控制对象，应该在调用本接口之前，先调用 `IEC61850_ControlSelect()` 接口对其执行操作前选择。<br>
	选择成功后才可以对其执行操作命令，操作命令需要在选择超时之前执行。<br>
	同时，操作命令附带的控制值和控制参数，也需要与操作前选择命令（Select / SelectWithValue）中的一致。
	<br>
	带有 Oper.operTm 数据属性的控制对象，将被视为时间激活的控制对象，<br>
	对其执行的操作命令将按照 时间激活的操作（TimeActivatedOperate）来处理，<br>
	需要在 `param` 参数中指定激活控制的操作时间。若时间激活的控制对象是 SBOes 的，则指定的操作时间也需要与带值选择（SelectWithValue）命令中的一致。<br>
	<br>
	该接口为客户端使用的接口，服务端禁止调用。

	\ingroup	Control

	\see	IEC61850_ControlOperate(), IEC61850_ControlOperateWithShortAddr()

	\param[in]	client			IEC61850 对象。<br>对象角色必须是客户端 `IEC61850_CLIENT`
	\param[in]	aaIndex 		连接服务端的连接序号
	\param[in]	ctlRef			控制对象 DO 的引用。例如 `LDName/CSWI0.Pos`
	\param[in]	operateValue	操作命令的控制值<br>操作 SBOes 控制对象时，需要与带值选择（SelectWithVal）命令的控制值一致。
	\param[in]	param			控制参数。<br>用于指定控制请求的 同期检查（SynchroCheck）、互锁检查（Interlock\-Check）、测试（Test）属性，以及时间激活控制的操作时间（operTm）。<br>操作 SBOns / SBOes 控制对象时，需要与操作前选择（Select / SelectWithVal）命令的控制参数一致。

	\return	错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。
*/
PIS10_API IEC61850_ErrorCode IEC61850_ControlOperateWithRef(IEC61850 client, int aaIndex, char* ctlRef, IEC61850_DataAttributeData* operateValue, IEC61850_ControlParameters* param);

/*!	\brief	取消。（基于引用）
	\details
	控制服务接口。用于对指定引用的控制对象执行取消命令。<br>
	对应的 ACSI 服务接口为：\"Cancel\"。<br>
	该接口可用于取消对控制对象的操作前选择（Select / SelectWithValue），以及用于取消尚未到达激活操作时间的时间激活操作（TimeActivatedOperate）。<br>
	取消命令附带的控制值和控制参数，需要与要被取消的控制命令（Select / SelectWithValue / TimeActivatedOperate）的控制值和控制参数一致。<br>
	<br>
	该接口为客户端使用的接口，服务端禁止调用。

	\ingroup	Control

	\see	IEC61850_ControlCancel(), IEC61850_ControlCancelWithShortAddr()

	\param[in]	client			IEC61850 对象。<br>对象角色必须是客户端 `IEC61850_CLIENT`
	\param[in]	aaIndex 		连接服务端的连接序号
	\param[in]	ctlRef			控制对象 DO 的引用。例如 `LDName/CSWI0.Pos`
	\param[in]	operateValue	取消命令的控制值。<br>需要与要被取消的控制命令（SelectWithVal / TimeActivatedOperate）的控制值一致。<br>取消对 SBOns 控制对象的操作前选择（Select）时，应指定为 NULL。
	\param[in]	param			控制参数。<br>用于指定控制请求的 同期检查（SynchroCheck）、互锁检查（Interlock\-Check）、测试（Test）属性，以及时间激活控制的操作时间（operTm）。<br>需要与要被取消的控制命令（Select / SelectWithVal / TimeActivatedOperate）的控制参数一致。

	\return	错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。
*/
PIS10_API IEC61850_ErrorCode IEC61850_ControlCancelWithRef(IEC61850 client, int aaIndex, char* ctlRef, IEC61850_DataAttributeData* operateValue, IEC61850_ControlParameters* param);

/*!	\brief	命令终止。
	\details
	控制服务接口。用于对指定 sAddr 的控制对象执行取消（Cancel）命令。<br>
	该接口的功和使用方法，与 `IEC61850_ControlCancel()` 接口相同，只是第二个参数由控制对象的 DAID 更换为了 sAddr。<br>
	该接口为客户端使用的接口，服务端禁止调用。

	\ingroup	Control

	\param[in]	server		IEC61850 对象。<br>对象角色必须是服务端 `IEC61850_SERVER` 
	\param[in]	dataMap		控制对象 控制值 Oper\.ctlVal 的数据属性映射。<br>可指定为 DAID 或 sAddr，应与同一控制序列的控制请求所使用的数据属性映射类型保持一致。<br>若指定为数据属性ID，则该参数为 `const IEC61850_DataAttributeID*` 类型<br>若指定为短地址，则该参数为 `const char*` 类型。
	\param[in]	addCause	命令终止的附加原因（AddCause）<br>对于成功的操作结果，需指定为 `IEC61850_COMMAND_ERROR_ADD_CAUSE_NONE`；<br>对于失败的操作结果，应按需指定为适用于当下控制状态机的合理 AddCause。 IEC61850-7-2 - 17.5.2.6

	\return	错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	<b>示例</b>
	\code
	IEC61850_ErrorCode result = S_OK;
	IEC61850_DataAttributeID daid = {1, 3, 3, 7, 0};
	eCommandAddCause addCause = IEC61850_COMMAND_ERROR_ADD_CAUSE_UNKNOWN;

	// Set the Command Termination cause, from  eCommandAddCause in the API
	addCause = IEC61850_COMMAND_ERROR_NONE;

	// Call the API to send the Command Termination for the given control
	result =  IEC61850_ControlTerminateCommand(myIEC61850Server, &daid, addCause);
	if (result == S_OK) {
		printf("Manual Command Termination sent Successfully\n");
	} else {
		printf("Sending Command Termination Failed: %i: %s\n", result, IEC61850_ErrorString(result));
	}
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_ControlTerminateCommand(IEC61850 server, void* dataMap, eCommandAddCause addCause);

/*!	\brief	该接口用于打印数据属性(DAID)
	\ingroup	Support

	\param[in]	daid	要打印的数据属性ID

	\return		无返回值
*/
PIS10_API void IEC61850_PrintDataAttributeID(const IEC61850_DataAttributeID* daid);

/*!	\brief	该接口用于打印数据属性值
	\ingroup	Support

	\param[in]	value	要打印的数据属性值

	\return		无返回值
*/
PIS10_API void IEC61850_PrintDataAttributeData(const IEC61850_DataAttributeData* value);

/*!	\brief	该接口用于获取客户端模型中引用的所有服务端的 IED 的状态，包括接入点信息。
	\details
	该接口为客户端使用的接口，服务端禁止调用。

	\ingroup	Support

	\param[in]	client	IEC61850 对象。<br>对象角色必须是客户端 `IEC61850_CLIENT`

	\return		服务端状态信息列表
*/
PIS10_API IEC61850_ServerStatusArray* IEC61850_PollServers(IEC61850 client);


/*!	\brief	该接口用于将指定的日期时间转换为 IEC61850 时间戳 `IEC61850_TimeStamp` 。
	\details
	转换后的 IEC61850 时间戳，将被写入由 `outTimestamp` 参数指定的 `IEC61850_TimeStamp` 数据中；<br>
	要被转换的日期时间通过其他的各个参数传入。<br>
	<br>
	通过 `IEC61850_SetTimeQuality()` 接口设置的时间品质，会应用到该接口传出的时间戳中。

	\ingroup	Time

	\param[in,out]	outTimestamp	IEC61850 的时间戳
	\param[in]		month			月。取值应为 1~12
	\param[in]		day				日。取值应为 1~31 
	\param[in]		year			年。取值应大于等于 1970
	\param[in]		hour			时。取值应为 0~23
	\param[in]		minute			分。取值应为 0~59
	\param[in]		second			秒。取值应为 0~59
	\param[in]		microseconds	微秒。取值应为 0~999999

	\return		错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	<b>示例</b>
	\code
	IEC61850_ErrorCode error = S_OK;
	IEC61850_TimeStamp t = { 0 };
	U8 month = 7;
	U8 day = 31;
	U16 year = 2015;
	U8 hour = 6;
	U8 minute = 4;
	U8 second = 44;
	U32 microseconds = 0;

	error = IEC61850_GetIEC61850TimeFromDate(&t, month, day, year, hour, minute, second, microseconds);
	if (error != S_OK) {
		printf("Failed to Convert time: %s (%d)", IEC61850_ErrorString(error), error);
	} else {
		printf(" Seconds since Epoch = %u \n", t.seconds);
	}
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_GetIEC61850TimeFromDate(IEC61850_TimeStamp* outTimestamp, U8 month, U8 day, U16 year, U8 hour, U8 minute, U8 second, U32 microseconds);


/*!	\brief	该接口用于将指定的 IEC61850 时间戳 IEC61850_TimeStamp 转换为日期时间 IEC61850_DateTime （年、月、日、时、分、秒、微秒）。
	\details
	指定的 IEC61850 时间戳由 `inTimestamp` 参数传入；<br>
	转换后的日期时间，将被写入由 `outDateTime` 参数指定的 `IEC61850_DateTime` 数据中。

	\ingroup	Time

	\param[in,out]	outDateTime	日期时间
	\param[in]		inTimestamp	IEC61850 的时间戳

	\return		错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	<b>示例</b>
	\code
	IEC61850_ErrorCode error = S_OK;
	IEC61850_DateTime dateTime = { 0 };
	IEC61850_TimeStamp timestamp = { 0 };

	timestamp.seconds = 1438322683;

	error = IEC61850_GetDateFromIEC61850Time(&dateTime, &timestamp);
	if (error != S_OK) {
		printf("Failed to Convert time: %s (%d)", IEC61850_ErrorString(error), error);
	} else {
		printf(" %02u/%02u/%u %02u:%02u:%02u \n", dateTime.month, dateTime.tm_mday, dateTime.year, dateTime.tm_hour, dateTime.tm_min, dateTime.tm_sec);
	}
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_GetDateFromIEC61850Time(IEC61850_DateTime* outDateTime, const IEC61850_TimeStamp* inTimestamp);

/*!	\brief	控制服务接口。用于设置客户端控制命令发起者信息（发起者角色(orCat) 和 发起者标识(orIdent)）。
	\details
	该接口为客户端使用的接口，服务端禁止调用。<br>
	每个客户端对应的控制命令发起者信息，通常是单一且固定不变的，<br>
	可以在创建了客户端的 IEC61850 对象，并加载完模型文件之后，在启动客户端之前调用该接口，并指定 `controlID` 参数为 NULL，进行统一设置。<br>

	\ingroup	Control

	\param[in]	client		IEC61850 对象。<br>对象角色必须是客户端 `IEC61850_CLIENT`
	\param[in]	controlID	控制对象 控制值 Oper\.ctlVal 的 DAID。<br>
							若指定为具体的 DAID，则设置的发起者信息将应用于指定的控制对象；<br>
							若指定为 NULL，则设置的发起者信息将应用于所有的控制对象。
	\param[in]	orCat		控制命令的发起者角色（orCat）
	\param[in]	orIdent		控制命令的发起者标识（orIdent）。<br>
							指定该值为 NULL 时，会默认将发起者标识设置为客户端的 IP 地址。
	\param[in]	orIdentSize	控制命令的发起者标识数据大小

	\return		错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	<b>示例</b>
	\code
	IEC61850_ErrorCode result = S_OK;
	IEC61850_DataAttributeID daid = {2, 1, 0, 0, 0};
	eOriginatorCat orCat = ORCAT_BAY_CONTROL;
	char orIdent[] = "192.168.1.100";	// set orIdent as IP address
	orIdentSize = 13;	// the size of orIdent

	result = IEC61850_SetOriginator(client, &daid, orCat, orIdent, orIdentSize);
	if (result == S_OK) {
		printf("Set originator success\n");
	} else {
		printf("Set originator failed: (%d) %s\n", result, IEC61850_ErrorString(result));
	}
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_SetOriginator(IEC61850 client, IEC61850_DataAttributeID* controlID, eOriginatorCat orCat, char* orIdent, U8 orIdentSize);

/*!	\brief	控制服务接口。用于给指定的控制对象设置新的控制序列号（ctlNum）。
	\details
	该接口为客户端调用的接口，服务端禁止调用。<br>
	<br>
	控制序列号（ctlNum）是 操作前选择、操作、取消 控制命令的请求参数之一。<br>
	默认情况下，客户端通过调用 操作前选择、操作、取消 控制命令接口所发出的控制请求，附带的控制序列号均为 0。<br>
	调用该接口后，会使指定控制对象的控制序列号（ctlNum）自增 1。<br>
	后续对于该控制对象所发起的控制命令，控制请求中附带的控制序列号都将为自增后的值。<br>
	<br>
	控制序列号的值，可由客户端自行决定。<br>
	但属于同一控制序列的所有控制命令（即，对于某个控制对象执行一次完整控制所发出的所有控制请求），需使用相同的控制序列号。

	\ingroup	Control

	\param[in]	client		IEC61850 对象。<br>对象角色必须是客户端 `IEC61850_CLIENT` 
	\param[in]	controlID	控制对象 控制值 Oper\.ctlVal 的 DAID

	\return		错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。
*/
PIS10_API IEC61850_ErrorCode IEC61850_SetNewCtlNum(IEC61850 client, IEC61850_DataAttributeID* controlID);

/*!	\brief	该接口用于获取连接状态信息。
	\details
	`iec61850` 参数用于指定要确认连接状态的客户端或服务端对象，<br>
	若对象角色是客户端 `IEC61850_CLIENT`，则 `connections` 内容为客户端模型中引用的各个服务端（ServerIED）的连接状态列表；<br>
	若对象角色是服务端 `IEC61850_SERVER`，则 `connections` 内容为当前与服务端处于关联成功状态的客户端的列表。

	\ingroup	Support

	\param[in]	iec61850		IEC61850 对象
	\param[out]	connectionList	与 `iec61850` 对应的连接状态信息列表 

	\return		错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	\remark
	服务端获取的 connectionList->connections[index].iedName 无值

	<b>示例</b>
	\code
	IEC61850_ErrorCode error = S_OK;
	ConnectionList connectionList = { 0 };
	error = IEC61850_GetConnectionsList(iec61850, &connectionList);
	if (error == S_OK) {
		if (connectionList && (connectionList.length > 0)) {
			U32 index = 0;
			// Print the list
			printf("\n\tConnected Servers (%u):\n", connectionList.length);
			printf("\tIndex\tIED Name\t\tIP address\tConnection Status\n");
			for (index = 0; index < connectionList.length; index++) {
				printf("\t%u\t%s\t%s\t%s\n",
					connectionList.connections[index].AAIndex,
					connectionList.connections[index].iedName,
					connectionList.connections[index].IPAddress,
					connectionList.connections[index].bConnectionState ? "Connected" : "Disconnected");
			}
		} else {
			printf("\n\t No remote connections present\n");
		}
	}
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_GetConnectionsList(IEC61850 iec61850, ConnectionList* connectionList);

/*!	\brief	读文件属性值。
	\details
	对应的 ACSI 服务接口为：\"GetFileAttributeValues\"。<br>
	该接口为客户端使用的接口，服务端禁止调用。<br>
	该接口调用后，需要调用 `IEC61850_DestroyFileAttributeValues()` 接口来释放 `fileAttributes` 中的读取结果。

	\ingroup	File

	\param[in]	client			IEC61850 对象。<br>对象角色必须是客户端 `IEC61850_CLIENT`
	\param[in]	serverIndex		服务端的索引号
	\param[in]	filename		ACSI 服务接口 GetFileAttributeValues 的请求数据。<br>服务端的文件名。<br>`filename` 通常指定为一个文件目录，以读取该目录下的所有文件信息。<br>目录末尾的 \"/\" 可以省略。例如：\"dirName\"、\"dirName/\"、\"dir1/dir2\"、\"dir1/dir2/\"；<br>也可以指定 `filename` 为某个文件。若指定为单一文件时，将仅读取该文件的属性信息；<br>若 `filename` 指定为空字符串（\"\"），则默认读取服务端文件处理根目录下的文件信息。
	\param[in]	continueAfter	用于指示读取 `continueAfter` 之后的文件属性值。<br>`continueAfter` 指定为 NULL 或者空字符串（\"\"）时，无作用。<br>指定为某个文件时，将返回 `continueAfter` 所指定的文件之后的文件属性值。<br>`continueAfter` 的内容规则，同 `filename` 参数。
	\param[out]	fileAttributes	ACSI 服务接口 GetFileAttributeValues 的响应数据。<br>文件属性值列表。<br>获取到的文件属性值列表，将通过 `fileAttributes->directoryEntries` 传出；其内容为 `struct tFile` 的数组，数组元素的数量，由 `fileAttributes->numOfDirectoryEntries` 指示。

	\return	错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	\see	IEC61850_DestroyFileAttributeValues()

	<b>示例</b>
	\code
	IEC61850_ErrorCode error = S_OK;
	tFileAttr attr = { 0 };

	error = IEC61850_GetFileAttributeValues(iec61850, connectedServerIndex, "/path/to/directory", NULL, &attr);
	if (error != S_OK) {
		printf("Get file attributes failed: %i: %s\n", error, IEC61850_ErrorString(error));
	} else {
		// Print list of files and attributes
		U32 index = 0;
		printf("Received attributes for %u file(s):\n", attr.numOfDirectoryEntries);
		printf("\tFile\tTimestamp\tSize [Bytes]\tFile Name\n");
		for (index = 0; index < attr.numOfDirectoryEntries; index++) {
			printf("\t%d:\t%s\t%u\t\t%s\n", index + 1, attr.directoryEntries[index].lastModified, attr.directoryEntries[index].fileSize, attr.directoryEntries[index].fileName);
		}
		IEC61850_DestroyFileAttributeValues(&attr);
	}
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_GetFileAttributeValues(IEC61850 client, unsigned int serverIndex, const char* filename, const char* continueAfter, struct tFileAttr* fileAttributes);

/*!	\brief	释放动态分配的文件属性值数据
	\ingroup	File

	\param[in]	fileAttributes	文件属性值数据

	\return	错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	\see	IEC61850_GetFileAttributeValues()

	<b>示例</b>
	\code
	IEC61850_ErrorCode error = S_OK;
	unsigned int serverIndex = 0;
	tFileAttr attr = { 0 };
	error = IEC61850_GetFileAttributeValues(client, serverIndex, "/path/to/directory", NULL, &attr);
	if (error == S_OK) {
		IEC61850_DestroyFileAttributeValues(&attr);
	}
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_DestroyFileAttributeValues(tFileAttr* fileAttributes);

/*!	\brief	写文件。
	\details
	对应的 ACSI 服务接口为：\"SetFile\"。<br>
	该接口为客户端使用的接口，服务端禁止调用。<br>
	<br>
	接口中指定的文件名，都必须是相对于文件处理的根目录的完整路径。有扩展名的文件，需包含扩展名。<br>
	例如：\"fileWithoutExt\"、\"file\.ext\"、\"dir/file\"、\"dir1/dir2/file\.ext\"。<br>
	<br>
	该接口不会创建文件名路径中缺失的目录层级。路径不存在时，操作将会失败。<br>

	\ingroup	File

	\param[in]	client			IEC61850 对象。<br>对象角色必须是客户端 `IEC61850_CLIENT`
	\param[in]	serverIndex		服务端的索引号
	\param[in]	remoteFileName	ACSI 服务接口 SetFile 的请求数据。<br>文件写到服务端后，在服务端保存的文件名。
	\param[in]	localFileName	ACSI 服务接口 SetFile 的请求数据。<br>本地待写（上传）到服务端的文件的文件名。<br>作为写文件的数据来源。

	\return		错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	<b>示例</b>
	\code
	IEC61850_ErrorCode error = S_OK;
	unsigned int serverIndex = 0;
	error = IEC61850_SetFile(client, serverIndex, "1.txt", "2.txt");
	\endcode

	\code
	// Client side File Callback example for SetFile
	IEC61850_FileResponseCode FileCallbackHandler(void* userData, IEC61850_FileCallType fileCallType, tFileAttr* fileAttributes)
	{
		IEC61850_FileResponseCode responseCode = IEC61850_FILE_RESPONSE_ACCEPT;
		switch(fileCallType)
		{
			case IEC61850_FILE_CALL_READ:	//This File is being obtained by the server from the client
				printf("local file being sent to server: %s\n", fileAttributes->primaryFile.fileName);
				//Only allow IED1.cid to be obtained by the client
				if (strcmp(fileAttributes->primaryFile.fileName, "MyFiles\IED1.cid") == 0) {
					responseCode = IEC61850_FILE_RESPONSE_ACCEPT;
				} else {
					responseCode = IEC61850_FILE_RESPONSE_ACCESS_DENIED;
				}
				break;
			case IEC61850_FILE_CALL_SET_FILE_COMPLETE:	//!< Set File transfer is complete.	Callback: The primary file is the local file, and the directory entries list contains the remote filename
				printf("Set file from completed successfully. Local file '%s', bytes written to disk '%u'\n", fileAttributes->primaryFile.fileName, fileAttributes->primaryFile.fileSize);
				break;
			case IEC61850_FILE_CALL_SET_FILE_FAIL:	//!< Set File Transfer has Failed - Partial file may be on the file system.  Callback: The primary file is the local file, and the directory entries list contains the remote filename
				printf("Set file from FAILED. Local file '%s', bytes written to disk '%u'\n", fileAttributes->primaryFile.fileName, fileAttributes->primaryFile.fileSize);
				break;
			default:
				printf("Unknown file call type %d\n", fileCallType);
				break;
		}
		return responseCode;
	}
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_SetFile(IEC61850 client, unsigned int serverIndex, const char* remoteFileName, const char* localFileName);

/*!	\brief	读文件。
	\details
	对应的 ACSI 服务接口为：\"GetFile\"。<br>
	该接口为客户端使用的接口，服务端禁止调用。<br>
	<br>
	接口中指定的文件名，必须是相对于文件处理根目录 的完整路径，且应保证所有层级的目录均存在。有扩展名的文件，需包含扩展名。<br>
	例如：\"fileWithoutExt\"、\"file\.ext\"、\"dir/file\"、\"dir1/dir2/file\.ext\"。<br>
	<br>
	该接口不会创建文件名路径中缺失的目录层级。路径不存在时，操作将会失败。

	\ingroup	File

	\param[in]	client			IEC61850 对象。<br>对象角色必须是客户端 `IEC61850_CLIENT`
	\param[in]	serverIndex		服务端的索引号
	\param[in]	remoteFileName	ACSI 服务接口 GetFile 的请求数据。<br>要读取（下载）的服务端的文件名。
	\param[in]	localFileName	文件读取（下载）到本地后，在本地保存的文件名。

	\return		错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	<b>示例</b>
	\code
	IEC61850_ErrorCode error = S_OK;
	unsigned int serverIndex = 0;
	error = IEC61850_GetFile(client, serverIndex, "1.txt", "2.txt");
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_GetFile(IEC61850 client, unsigned int serverIndex, const char* remoteFileName, const char* localFileName);

/*!	\brief	删除文件。
	\details
	对应的 ACSI 服务接口为：\"DeleteFile\"。<br>
	该接口为客户端使用的接口，服务端禁止调用。<br>

	接口中指定的文件名，都必须是相对于文件处理的根目录的完整路径。有扩展名的文件，需包含扩展名。<br>
	指定为纯目录时，末尾的 "/" 可以省略。<br>
	例如：\"fileWithoutExt\"、\"file\.ext\"、\"dir/file\"、\"dir1/dir2/file\.ext\"、\"dir1/dir2\"、\"dir1/dir2/\"。<br>
	<br>
	该接口可以删除文件目录，但仅有空的目录才可以被删除，删除非空的目录会失败，必须先删除该目录中的所有文件，才能删除该目录。<br>

	\ingroup	File

	\param[in]	client				IEC61850 对象。<br>对象角色必须是客户端 `IEC61850_CLIENT`
	\param[in]	serverIndex			服务端的索引号
	\param[in]	fileNameToDelete	ACSI 服务接口 DeleteFile 的请求数据。<br>要删除的服务端的文件名。

	\return		错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	<b>示例</b>
	\code
	IEC61850_ErrorCode error = S_OK;
	unsigned int serverIndex = 0;
	error = IEC61850_DeleteFile(client, serverIndex, "/path/to/file.txt");
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_DeleteFile(IEC61850 client, unsigned int serverIndex, const char* fileNameToDelete);

/*!	\brief	该接口用于获取指定 DAID 对应数据属性的数据值。
	\details
	该接口为服务端使用的接口，客户端禁止调用。

	\ingroup	DataAttributeAccess

	\param[in]		server			IEC61850 对象。<br>对象角色必须是服务端 `IEC61850_SERVER`
	\param[in]		daid			DAID
	\param[in,out]	outReturnValue	数据值

	\return	错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。
*/
PIS10_API IEC61850_ErrorCode IEC61850_GetDataAttributeData(IEC61850 server, IEC61850_DataAttributeID* daid, IEC61850_DataAttributeData* outReturnValue);


/*!	\brief	该接口用于以指定的 DAID 换取对应数据属性的 MMS 格式的 FCDA 引用。
	\details
	该接口客户端和服务端均可以使用。

	\ingroup	DataAttributeAccess

	\param[in]		iec61850		IEC61850 对象
	\param[in]		daid			DAID
	\param[in,out]	outMMSString	MMS 格式的 FCDA 引用。<br>例如 \"LDName/CSWI0\$ST\$Pos\$stVal\"。<br>该参数需要传入一个容量至少为 130 的字符串数组的地址。<br>以确保可以保存最大长度的对象引用字符串。（最大长度129 \+ 字符串结束符 \'\\0\'）

	\return	错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。
*/
PIS10_API IEC61850_ErrorCode IEC61850_GetMMSStringForPrivateID(IEC61850 iec61850, IEC61850_DataAttributeID* daid, char* outMMSString);

/*!	\brief	该接口用于以指定的 MMS 格式的 FCDA 引用，换取对应数据属性的 DAID。
	\details
	该接口客户端和服务端均可以使用。

	\ingroup	DataAttributeAccess

	\param[in]		iec61850	IEC61850 对象
	\param[in]		mmsString	MMS 格式的 FCDA 引用。<br>例如 \"LDName/CSWI0\$ST\$Pos\$stVal\"。
	\param[in,out]	outDAID		DAID

	\return	错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。
*/
PIS10_API IEC61850_ErrorCode IEC61850_GetPrivateIDForMMSString(IEC61850 iec61850, const char* mmsString, IEC61850_DataAttributeID* outDAID);

/*!	\brief	该接口用于获取服务端所有 GOOSE 控制块的基本信息。
	\details
	获取到的信息包括每个 GOOSE 控制块的引用（MMS 协议格式，<br>
	例如 \"LDName/LLN0\$GO\$GoCBName\"）、使能状态（goEna）、是发布端还是订阅端，以及 GOOSE 控制块所关联的、配置有 DAID 的数据属性的 DAID 列表。

	\ingroup	DataAttributeAccess

	\param[in]		server				IEC61850 对象。<br>对象角色必须是服务端 `IEC61850_SERVER`
	\param[in,out]	outGOOSECBArray		获取到的 GOOSE 控制块信息列表。<br>是一个 `struct GOOSEControlBlocks` 数组的地址，数组的元素数量由出参 `outGOOSECBArraySize` 指示。
	\param[in,out]	outGOOSECBArraySize	获取到的 GOOSE 控制块数量。<br>用于指示 `outGOOSECBArray` 参数中的元素数量。

	\return	错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	<b>示例</b>
	\code
	IEC61850_ErrorCode error = S_OK;
	GOOSEControlBlocks *outGOOSECBArray = NULL;
	U32 outGOOSECBArraySize = 0;
	U32 i = 0;

	error = IEC61850_GetGOOSEControlBlockInfo(iec61850, &outGOOSECBArray,  &outGOOSECBArraySize);

	printf("Number of GOOSE Control Blocks %d \n", outGOOSECBArraySize );

	for (i = 0; i < outGOOSECBArraySize; i++) {
		printf("GoCB %d = %s\n",i ,outGOOSECBArray[i].gocbRef);
	}

	//once finished free the DAIDArrays in each GOOSE CB element
	for (i = 0; i < outGOOSECBArraySize; i++) {
		free(outGOOSECBArray->daidArray);
	}

	free(outGOOSECBArray);
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_GetGOOSEControlBlockInfo(IEC61850 server, GOOSEControlBlocks** outGOOSECBArray, U32* outGOOSECBArraySize);

/*!	\brief	该接口用于获取模型中配置有 DAID 的数据属性信息。
	\details
	该接口服务端和客户端均可以调用，获取到的数据属性信息由 `outDAInfoArr` 参数传出。<br>
	不同的角色调用，`outDAInfoArr` 的内容会有所不同，具体参照参数的说明。

	\ingroup		DataAttributeAccess

	\param[in]		iec61850		IEC61850 对象
	\param[in,out]	outDAInfoArr	数据属性信息。<br>
									若该参数为 NULL，则 `outArrSize` 参数将返回模型文件中所有配置了 DAID 的数据属性的总数量减1。（假设模型中有 20 个数据属性配置 DAID，则该值将返回 19）；<br>
									若该参数不为 NULL，则应为一个容量不小于 `outArrSize` 的 `struct DAInfo` 数组的首地址。<br>
									若 `iec61850` 参数为服务端 `IEC61850_SERVER`，则获取到的 `outDAInfoArr` 中，会附带数据属性值，且数据属性的名称为 ObjectName（例如 stVal）；<br>
									若 `iec61850` 参数为客户端 `IEC61850_CLIENT`，则获取到的 `outDAInfoArr` 中，不会附带据属性值（数据属性值为 NULL），且数据属性的名称为 MMS 的 FCDA 引用。例如 `CSWI0$ST$Pos$stVal`。
	\param[in,out]	outArrSize		数据属性数量。<br>
									若 `outDAInfoArr` 参数为 NULL，则该参数返回的数值，为模型文件中所有配置了 DAID 的数据属性总数量减1。即，假设模型中有给 10 个数据属性配置 DAID，则返回的该参数值为 9；<br>
									若 `outDAInfoArr` 参数不为 NULL，则该参数代表从 `startAt` 参数指定索引开始的、当次请求所能够返回的最大数据属性数量。接口返回后，该入参值将被实际返回的数据属性数量替代。
	\param[in]		startAt			起始索引。<br>用于指定返回的数据属性从第几个开始。<br>初始索引值从 0 开始，值不能超过可以返回的数据属性总数量减 1。

	\return		错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	<b>示例</b>
	\code
	IEC61850_ErrorCode error = S_OK;
	DAInfo daInfoArr[50] = { 0 };
	U32 totalDataPoints = 0;
	U32 daArrSize = 0;
	U32 continueAfter = 0;
	U32 i = 0;

	error = IEC61850_GetDataAttributesInfo(GetMyServerClient(inServerClientIndex), NULL, &totalDataPoints, 0);
	printf("Number of Data attributes %u \n", totalDataPoints);

	while (continueAfter < totalDataPoints) {
		daArrSize = 50;
		IEC61850_GetDataAttributesInfo(GetMyServerClient(inServerClientIndex), daInfoArr, &daArrSize, continueAfter);
		continueAfter += daArrSize;

		for (i = 0; i < daArrSize; i++) {
			//Print Item Name
			printf("Name: %s\n", daInfoArr[i].name);
			IEC61850_PrintDataAttributeID(daInfoArr[i].DAID);
			printf("\n");
		}
	}
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_GetDataAttributesInfo(IEC61850 iec61850, DAInfo* outDAInfoArr, U32* outArrSize, U32 startAt);

/*!	\brief	按时间查询日志。
	\details
	对应的 ACSI 服务接口为：\"QueryLogByTime\"。<br>
	该接口为客户端使用的接口，服务端禁止调用。

	\ingroup	LCB

	\param[in]		client				IEC61850 对象。<br>对象角色必须是客户端 `IEC61850_CLIENT`
	\param[in]		serverIndex			服务端的索引号
	\param[in]		logRef				ACSI 服务接口 QueryLogByTime 的请求数据。<br>日志的引用。
	\param[in]		startTime			ACSI 服务接口 QueryLogByTime 的请求数据。<br>起始时间。
	\param[in]		stopTime			ACSI 服务接口 QueryLogByTime 的请求数据。<br>结束时间。
	\param[in,out]	returnedLogEntries	ACSI 服务接口 QueryLogByTime 的响应数据。<br>日志条目列表。

	\return	错误码。<br>成功则返回  #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。
	
	<b>示例</b>
	\code
	IEC61850_ErrorCode result = S_OK;

	IEC61850_TimeStamp startTime = { 0 };
	IEC61850_TimeStamp stopTime = { 0 };
	IEC61850_LogEntries entries = { 0 };

	char* logRef = "ServerIEDExample/LLN0.logName";
	result = IEC61850_GetIEC61850TimeFromDate(&startTime, 2, 25, 2019, 0, 0, 0, 0);
	result = IEC61850_GetIEC61850TimeFromDate(&stopTime, 3, 2, 2019, 12, 13, 11, 0);

	result = IEC61850_QueryLogByTime(GetMyServerClient(), logRef, &startTime, &stopTime, &entries);
	// // if No limit on start time and stop time
	// result = IEC61850_QueryLogByTime(GetMyServerClient(), logRef, NULL, NULL, &entries);

	IEC61850_FreeLogEntries(&entries);
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_QueryLogByTime(IEC61850 client, unsigned int serverIndex, char* logRef, IEC61850_TimeStamp* startTime, IEC61850_TimeStamp* stopTime, struct IEC61850_LogEntries* returnedLogEntries);

/*!	\brief	查询指定条目之后的日志。
	\details
	对应的 ACSI 服务接口为：\"QueryLogAfter\"。<br>
	该接口为客户端使用的接口，服务端禁止调用。

	\ingroup	LCB

	\param[in]		client				IEC61850 对象。<br>对象角色必须是客户端 `IEC61850_CLIENT`
	\param[in]		serverIndex			服务端的索引号
	\param[in]		logRef				ACSI 服务接口 QueryLogAfter 的请求数据。<br>日志的引用
	\param[in]		startTime			ACSI 服务接口 QueryLogAfter 的请求数据。<br>起始时间。
	\param[in]		entryID				ACSI 服务接口 QueryLogAfter 的请求数据。<br>日志条目ID（EntryID）。
	\param[in,out]	returnedLogEntries	ACSI 服务接口 QueryLogAfter 的响应数据。<br>日志条目列表。

	\return	错误码。<br>成功则返回  #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	<b>示例</b>
	\code
	IEC61850_ErrorCode result = S_OK;
	U32 entryId = 123;
	char* logRef = "ServerIEDExample/LLN0.logName";
	IEC61850_TimeStamp startTime = { 0 };
	IEC61850_LogEntries entries = { 0 };
	result = IEC61850_GetIEC61850TimeFromDate(&startTime, 2, 25, 2019, 0, 0, 0, 0);

	result = IEC61850_QueryLogAfter(GetMyServerClient(), logRef, &startTime, entryId, &entries);

	IEC61850_FreeLogEntries(&entries);
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_QueryLogAfter(IEC61850 client, unsigned int serverIndex, char* logRef, IEC61850_TimeStamp* startTime, U32 entryID, struct IEC61850_LogEntries* returnedLogEntries);

/*!	\brief	读日志状态值。
	\details
	对应的 ACSI 服务接口为：\"GetLogStatusValues\"。<br>
	该接口为客户端使用的接口，服务端禁止调用。<br>

	\attention
	该接口的 `ldName` 和 `logName` 参数稍微特殊，<br>
	参照 IEC61850-7-2:2010（DL/T 860.72:2013）的 17.3.5.4 章节，<br>
	ACSI \"GetLogStatusValues\" 的请求参数是日志的引用（logReference，例如：\"LDName/LLN0\.logName\"），<br>
	响应的数据为最新和最旧日志的条目时间和条目ID。<br>
	<br>
	参照 IEC61850-8-1:2011（DL/T 860.81:2016）的 17.3 章节，<br>
	该 ACSI 的响应数据，在 MMS 的映射中被合并到了日志控制块（LCB）的数据定义中，<br>
	因此，该接口映射到 MMS 协议之后，就变成了读取日志控制块的属性，<br>
	其请求参数也就变成了日志控制块实例的 MMS 映射（例如：\"LDName/LLN0\$LG\$LCBName\"）。

	\ingroup	LCB

	\param[in]		client				IEC61850 对象。<br>对象角色必须是客户端 `IEC61850_CLIENT`
	\param[in]		serverIndex			服务端的索引号
	\param[in]		ldName				ACSI 服务接口 GetLogStatusValues 的请求数据。<br>日志控制块对应的逻辑设备名称（LDName）。
	\param[in]		logName				ACSI 服务接口 GetLogStatusValues 的请求数据。<br>
										该参数应指定为日志控制块的 MMS Object Name。<br>
										例如：\"LLN0\$LG\$LCBName\"。其中的 \"LCBName\" 为日志控制块的名称。
	\param[in,out]	returnedLogStatus	ACSI 服务接口 GetLogStatusValues 的响应数据。<br>日志状态值。

	\return		错误码。<br>成功则返回  #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	<b>示例</b>
	\code
	IEC61850_ErrorCode result = S_OK;
	IEC61850_LogStatus status = { 0 };
	result = IEC61850_GetLogStatusValues(GetMyServerClient(), 0, "ServerIEDExample", "LLN0$LG$logCBName", &status);
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_GetLogStatusValues(IEC61850 client, unsigned int serverIndex, char* ldName, char* logName, IEC61850_LogStatus* returnedLogStatus);

/*!	\brief	释放动态分配的日志条目列表。
	\details
	该接口用于释放 `IEC61850_QueryLogByTime()` 和 `IEC61850_QueryLogAfter()` 接口的响应数据。

	\ingroup	LCB

	\param[in]	logger	日志条目列表

	\return	错误码。<br>成功则返回  #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。
*/
PIS10_API IEC61850_ErrorCode IEC61850_FreeLogEntries(IEC61850_LogEntries* logger);

/*!	\brief	读数据集目录。
	\details
	对应的 ACSI 服务接口为：\"GetDataSetDirectory\"。<br>
	该接口为客户端使用的接口，服务端禁止调用。<br>
	该接口用于释放 `IEC61850_QueryLogByTime()` 和 `IEC61850_QueryLogAfter()` 接口的响应数据。

	\ingroup	DataSet

	\param[in]	client					IEC61850 对象。<br>对象角色必须是客户端 `IEC61850_CLIENT`
	\param[in]	serverIndex				服务端的索引号
	\param[in]	datasetReference		ACSI 服务接口 GetDataSetDirectory 的请求数据。<br>数据集的引用。
	\param[out]	response				ACSI 服务接口 GetDataSetDirectory 的响应数据。<br>数据集 FCDA 成员引用的列表。

	\return		错误码。<br>成功则返回  #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。
*/
PIS10_API IEC61850_ErrorCode IEC61850_GetDataSetDirectory(IEC61850 client, unsigned int serverIndex, char* datasetReference, GetDataSetDirectory_Response* response);

/*!	\brief	创建数据集。
	\details
	对应的 ACSI 服务接口为：\"CreateDataSet\"。<br>
	该接口为客户端使用的接口，服务端禁止调用。

	\ingroup	DataSet

	\param[in]	client			IEC61850 对象。<br>对象角色必须是客户端 `IEC61850_CLIENT`
	\param[in]	serverIndex		服务端的索引号
	\param[in]	request			ACSI 服务接口 CreateDataSet 的请求数据
	\param[in]	serviceError	ACSI 服务接口 CreateDataSet 的响应数据。<br>响应的错误码。

	\return		错误码。<br>成功则返回  #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	<b>示例</b>
	\code
	IEC61850_ErrorCode result = S_OK;
	IEC61850 iec61850 = GetMyServerClient();
	unsigned int serverIndex = 0;
	CreateDataSet_Request request = { 0 };
	eServiceError serviceError;
	FCDA fcdaList[2] = { 0 };
	request.datasetReference = "ServerIEDExample/LLN0.PersistentDS";
	request.fcdaList = fcdaList;
	request.numOfFcda = 2;

	strcpy(fcdaList[0].DARef, "ServerIEDExample/LLN0.Beh.stVal");
	strcpy(fcdaList[1].DARef, "ServerIEDExample/LPHD0.Beh.stVal");
	strcpy(fcdaList[0].FC, "ST");
	strcpy(fcdaList[1].FC, "ST");

	result = IEC61850_CreateDataSet(iec61850, serverIndex, &request, &serviceError);

	return result;
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_CreateDataSet(IEC61850 client, unsigned int serverIndex, CreateDataSet_Request* request, int* serviceError);

/*!	\brief	删除数据集。
	\details
	对应的 ACSI 服务接口为：\"DeleteDataSet\"。<br>
	该接口为客户端使用的接口，服务端禁止调用。
		 
	\ingroup	DataSet

	\param[in]	client				IEC61850 对象。<br>对象角色必须是客户端 `IEC61850_CLIENT`
	\param[in]	serverIndex			服务端的索引号
	\param[in]	datasetReference	ACSI 服务接口 DeleteDataSet 的请求数据。<br>数据集的引用。
	\param[in]	serviceError		ACSI 服务接口 DeleteDataSet 的请求数据。<br>数据集的引用。

	\return	错误码。<br>成功则返回  #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	<b>示例</b>
	\code
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_DeleteDataSet(IEC61850 client, unsigned int serverIndex, char* datasetReference, int* serviceError);

/*!	\brief	获取数据集值。
	\details
	对应的 ACSI 服务接口为：\"GetDataSetValues\"。<br>
	该接口为客户端使用的接口，服务端禁止调用。

	\ingroup	DataSet

	\param[in]		client				IEC61850 对象。<br>对象角色必须是客户端 `IEC61850_CLIENT`
	\param[in]		serverIndex			服务端的索引号
	\param[in]		datasetReference	ACSI 服务接口 GetDataSetValues 的请求数据。<br>数据集的引用。
	\param[in,out]	response			ACSI 服务接口 GetDataSetValues 的返回数据。<br>数据集的值。

	\return	错误码。<br>成功则返回  #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	<b>示例</b>
	\code
	GetDataSetValues_Response response = { 0 };

	IEC61850_ErrorCode result = IEC61850_GetDataSetValues(GetMyServerClient(), 0, "ServerIEDExample/LLN0.GooseDS", &response);
	if (result == S_OK) {
		int i = 0;
		for (i = 0; i < response.dataNum; i++) {
			printf("index[%d]\n", i + 1);
			PrintDAVal(&response.dataAttributes[i], 2);
		}
	}
	FreeGetDataSetValues_Response(&response);
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_GetDataSetValues(IEC61850 client, unsigned int serverIndex, char* datasetReference, GetDataSetValues_Response* response);

/*!	\brief	写数据集值。
	\details
	对应的 ACSI 服务接口为：\"SetDataSetValues\"。<br>
	该接口为客户端使用的接口，服务端禁止调用。

	\ingroup 	DataSet

	\param[in]		client		IEC61850 对象。<br>对象角色必须是客户端 `IEC61850_CLIENT`
	\param[in]		serverIndex	服务端的索引号
	\param[in]		request		ACSI 服务接口 SetDataSetValues 的请求
	\param[in,out]	response	ACSI 服务接口 SetDataSetValues 的应答

	\return		错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。
*/
PIS10_API IEC61850_ErrorCode IEC61850_SetDataSetValues(IEC61850 client, unsigned int serverIndex, SetDataSetValues_Request* request, SetDataSetValues_Response* response);

/*!	\brief	该接口用于初始化一个字符串列表。
	\details
	初始化后，可通过 StringListAdd() 、StringListAddNew() 向字符串列表中添加元素。<br>
	使用该接口初始化的字符串列表，在使用之后需要使用 FreeStringList() 释放资源。

	\ingroup	DataSet

	\return		字符串列表

	<b>示例</b>
	\code
	StringList *ss = StringListMalloc();
	\endcode
*/
PIS10_API StringList* StringListMalloc();

/*!	\brief	该接口用于向初始化之后的字符串列表中添加字符串成员。
	\details
	调用该接口前，需要先调用 StringListMalloc() 对字符串列表进行初始化。

	\ingroup	Support

	\param[in]	strlist	字符串列表
	\param[in]	str		要添加到字符串列表中的字符串

	\return		添加成功时，为字符串列表中包含的字符串数量；添加失败时，返回 -1

	<b>示例</b>
	\code
	const char* c = "CCCCC";
	struct StringList *ss = StringListMalloc();
	StringListAdd(ss, "AAAAA");
	StringListAdd(ss, "BBBBB");
	StringListAdd(ss, c);
	\endcode
*/
PIS10_API int StringListAdd(StringList* strlist, char* str);

/*!	\brief	该接口用于向初始化之后的字符串列表中添加不重复的字符串成员。
	\details
	该接口的用法与 `StringListAdd()` 相同。<br>
	调用该接口前，需要先调用 `StringListMalloc()` 对字符串列表进行初始化。

	\ingroup	Support

	\param[in]	strlist	字符串列表
	\param[in]	str		要添加到字符串列表中的字符串

	\return		添加成功时，为字符串列表中包含的字符串数量；添加失败时，返回 -1
*/
PIS10_API int StringListAddNew(StringList* strlist, char* str);

/*!	\brief	该接口用于清理由 StringList
	\ingroup	Support

	\param[in]	list	要清空的字符串列表

	\return	无返回值
*/
PIS10_API void StringListClean(StringList* list);

/*!	\brief	该接口用于释放由 StringListMalloc() 接口初始化的字符串列表。
	\ingroup	Support

	\param[in,out]	list	要释放的字符串列表

	\return		无返回值
*/
PIS10_API void FreeStringList(StringList* list);

/*!	\brief	选择激活定值组。
	\details
	对应的 ACSI 服务接口为：\"SelectActiveSG\"。<br>
	该接口为客户端使用的接口，服务端禁止调用。

	\ingroup	SGCB

	\param[in]		client			IEC61850 对象。<br>对象角色必须是客户端 `IEC61850_CLIENT`
	\param[in]		serverIndex		服务端的索引号
	\param[in]		request			ACSI 服务接口 SelectActiveSG 的请求数据。<br>定值组控制块的引用和选择激活的定值组号。
	\param[in,out]	serviceError	ACSI 服务接口 SelectActiveSG 的响应数据。<br>选择激活定值组的响应结果。

	\return		错误码。<br>成功则返回  #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	<b>示例</b>
	\code
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_SelectActiveSG(IEC61850 client, unsigned int serverIndex, SelectActiveSG_Request* request, eServiceError *serviceError);

/*!	\brief	选择编辑定值组。
	\details
	对应的 ACSI 服务接口为：\"SelectEditSG\"。<br>
	该接口为客户端使用的接口，服务端禁止调用。

	\ingroup	SGCB

	\param[in]		client			IEC61850 对象。<br>对象角色必须是客户端 `IEC61850_CLIENT`
	\param[in]		serverIndex		服务端的索引号
	\param[in]		request			ACSI 服务接口 SelectEditSG 的请求数据。<br>定值组控制块的引用和选择编辑的定值组号。
	\param[in,out]	serviceError	ACSI 服务接口 SelectEditSG 的响应数据。<br>选择编辑定值组的响应结果。

	\return		错误码。<br>成功则返回  #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	<b>示例</b>
	\code
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_SelectEditSG(IEC61850 client, unsigned int serverIndex, SelectEditSG_Request* request, eServiceError* serviceError);

/*!	\brief	设置编辑定值组值。
	\details
	对应的 ACSI 服务接口为：\"SetEditSGValue\"。<br>
	该接口为客户端使用的接口，服务端禁止调用。<br>
	该接口仅应该在编辑定值组有效（EditSG ≠ 0）时调用。

	\ingroup	SGCB

	\param[in]		client		IEC61850 对象。<br>对象角色必须是客户端 `IEC61850_CLIENT`
	\param[in]		serverIndex	服务端的索引号
	\param[in]		request		ACSI 服务接口 SetEditSGValue 的请求数据。<br>编辑的定值数据信息。
	\param[in,out]	response	ACSI 服务接口 SetEditSGValue 的响应数据。<br>编辑定值的响应结果。

	\return	错误码。<br>成功则返回  #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	<b>示例</b>
	\code
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_SetEditSGValue(IEC61850 client, unsigned int serverIndex, SetEditSGValue_Request* request, SetEditSGValue_Response* response);

/*!	\brief	确定编辑定值组。
	\details
	对应的 ACSI 服务接口为：\"ConfirmEditSGValues\"。<br>
	该接口为客户端使用的接口，服务端禁止调用。<br>
	该接口仅应该在编辑定值组有效（EditSG ≠ 0）时调用。

	\ingroup	SGCB

	\param[in]	client			IEC61850 对象。<br>对象角色必须是客户端 `IEC61850_CLIENT`
	\param[in]	serverIndex		服务端的索引号
	\param[in]	sgcbReference	ACSI 服务接口 ConfirmEditSGValues 的请求数据。<br>确认编辑的定值组控制块的引用。
	\param[out]	serviceError	ACSI 服务接口 ConfirmEditSGValues 的响应数据。<br>响应的 ServiceError。

	\return		错误码。<br>成功则返回  #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	<b>示例</b>
	\code
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_ConfirmEditSGValues(IEC61850 client, unsigned int serverIndex, char* sgcbReference, eServiceError* serviceError);

/*!	\brief	读定值组控制块值。
	\details
	对应的 ACSI 服务接口为：\"GetSGCBValues\"。<br>
	该接口为客户端使用的接口，服务端禁止调用。

	\ingroup	SGCB

	\param[in]	client			IEC61850 对象。<br>对象角色必须是客户端 `IEC61850_CLIENT`
	\param[in]	serverIndex		服务端的索引号
	\param[in]	sgcbReference	ACSI 服务接口 GetSGCBValues 的请求数据。<br>请求读的定值组控制块的引用
	\param[out]	response		ACSI 服务接口 GetSGCBValues 的响应数据。<br>定值组控制块的值。

	\return		错误码。<br>成功则返回  #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	<b>示例</b>
	\code
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_GetSGCBValues(IEC61850 client, unsigned int serverIndex, char* sgcbReference, GetSGCBValues_Response* response);

/*!	\brief	读定值组值。
	\details
	对应的 ACSI 服务接口为：\"GetEditSGValue\"。<br>
	该接口为客户端使用的接口，服务端禁止调用。

	\ingroup	SGCB

	\param[in]	client		IEC61850 对象。<br>对象角色必须是客户端 `IEC61850_CLIENT`
	\param[in]	serverIndex	服务端的索引号
	\param[in]	request		ACSI 服务接口 GetEditSGValue 的请求数据。<br>请求读的定值的引用和功能约束。<br>指定功能约束为SG，则读的是当前激活的定值；<br>指定功能约束为SE，则读的是编辑区的定值。
	\param[out]	response	ACSI 服务接口 GetEditSGValue 的响应数据。<br>读定值的响应结果。

	\return		错误码。<br>成功则返回  #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。
*/
PIS10_API IEC61850_ErrorCode IEC61850_GetEditSGValue(IEC61850 client, unsigned int serverIndex, GetEditSGValue_Request* request, GetEditSGValue_Response* response);

/*!	\brief	该接口用于使能或取消使能报告控制块实例。
	\details
	该接口为客户端使用的接口，服务端禁止调用。<br>
	调用该接口时，需要已知 `rcbInstRef` 参数指定的报告控制块实例是缓存的（BRCB）还是非缓存的（URCB），并根据其类型指定 `bufferFlag` 参数值。

	\ingroup	Report

	\param[in]	client			IEC61850 对象。<br>对象角色必须是客户端 `IEC61850_CLIENT`
	\param[in]	serverIndex		服务端的索引号
	\param[in]	rcbInstRef		要使能或取消使能的报告控制块实例的引用。<br>例如：`LDName/LNName.RCBName01`
	\param[in]	buffered		`rcbInstRef` 对应的报告控制块的缓存类型标记。<br>
								若为缓存报告控制块（BRCB），则该参数必须指定为 TRUE；<br>
								若为非缓存报告控制块（URCB），则该参数必须指定为 FALSE。
	\param[in]	enable			要设置的使能状态。<br>TRUE：使能；<br>FALSE：取消使能

	\return		错误码。<br>成功则返回  #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	<b>示例</b>
	\code
	IEC61850_ErrorCode error = IEC61850_ERROR_NONE;
	IEC61850 myClient = GetMyServerClient();
	unsigned int serverIndex = 0;

	char* rcbInstRef = "ServerIEDExample/MMXU0.ExampleRCB01";
	Boolean buffered = FALSE;
	Boolean rptEna = TRUE;

	error = IEC61850_ReportEnable(myClient, serverIndex, rcbInstRef, buffered, rptEna);
	if (error != IEC61850_ERROR_NONE) {
		printf("failed. error=[%d]\n", error);
	} else {
		printf("success.\n");
	}
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_ReportEnable(IEC61850 client, unsigned int serverIndex, char* rcbInstRef, Boolean buffered, Boolean enable);

/*!	\brief	该接口用于对报告控制块实例请求总召唤（GI，general-interrogation）。
	\details
	该接口为客户端使用的接口，服务端禁止调用。<br>
	调用该接口时，需要已知 `rcbInstRef` 参数指定的报告控制块实例是缓存的（BRCB）还是非缓存的（URCB），并根据其类型指定 `bufferFlag` 参数值。

	\ingroup	Report

	\param[in]	client			IEC61850 对象。<br>对象角色必须是客户端 `IEC61850_CLIENT` 
	\param[in]	serverIndex		服务端的索引号
	\param[in]	rcbInstRef		要请求总召唤的报告控制块实例的引用。<br>例如：`LDName/LNName.RCBName01`
	\param[in]	buffered		`rcbInstRef` 对应的报告控制块的缓存类型标记。<br>
								若为缓存报告控制块（BRCB），则该参数必须指定为 TRUE；<br>
								若为非缓存报告控制块（URCB），则该参数必须指定为 FALSE。

	\return		响应的 ServiceError。<br>肯定响应时，值为 #SERVICE_ERROR_NO_ERROR (0) ；<br>否定响应时，值为其他非 0 值的 #eServiceError 枚举值。

	\note
	仅在报告控制块实例已经使能的情况下，才可以对其请求总召唤。<br>
	报告控制块实例未被使能时，调用该接口无法触发其上送总召唤报告；<br>
	报告控制块实例未启用总召唤的触发条件时，调用该接口也无法触发其上送总召唤报告。<br>
	该接口不具备使能报告控制块实例的功能。

	<b>示例</b>
	\code
	eServiceError error = SERVICE_ERROR_NO_ERROR;
	IEC61850 myClient = GetMyServerClient();
	unsigned int serverIndex = 0;

	char* rcbInstRef = "ServerIEDExample/MMXU0.ExampleRCB01";
	Boolean buffered = FALSE;

	error = IEC61850_ReportGI(myClient, serverIndex, rcbInstRef, buffered);
	if (error != SERVICE_ERROR_NO_ERROR) {
		printf("failed. error=[%d]\n", error);
	} else {
		printf("success.\n");
	}
	\endcode
*/
PIS10_API eServiceError IEC61850_ReportGI(IEC61850 client, unsigned int serverIndex, char* rcbInstRef, Boolean buffered);

/*!	\brief	读缓存报告控制块值。
	\details
	对应的 ACSI 服务接口为：\"GetBRCBValues\"。<br>
	该接口为客户端使用的接口，服务端禁止调用。

	\ingroup	BRCB

	\param[in]	client			IEC61850 对象。<br>对象角色必须是客户端 `IEC61850_CLIENT`
	\param[in]	serverIndex		服务端的索引号
	\param[in]	brcbReference	ACSI 服务接口 GetBRCBValues 的请求数据。<br>请求读的 BRCB 实例的引用。
	\param[out]	response		ACSI 服务接口 GetBRCBValues 的响应数据。<br>读 BRCB 的响应结果。

	\return		错误码。<br>成功则返回  #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	<b>示例</b>
	\code
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_GetBRCBValues(IEC61850 client, unsigned int serverIndex, char* brcbReference, GetBRCBValues_Response* response);

/*!	\brief	读非缓存报告控制块值。
	\details
	对应的 ACSI 服务接口为：\"GetURCBValues\"。<br>
	该接口为客户端使用的接口，服务端禁止调用。

	\ingroup	URCB

	\param[in]	client			IEC61850 对象。<br>对象角色必须是客户端 `IEC61850_CLIENT`
	\param[in]	serverIndex		服务端的索引号
	\param[in]	urcbReference	ACSI 服务接口 GetURCBValues 的请求数据。<br>请求读的 BRCB 实例的引用。
	\param[out]	response		ACSI 服务接口 GetURCBValues 的响应数据。<br>读 URCB 的响应结果。

	\return		错误码。<br>成功则返回  #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	<b>示例</b>
	\code
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_GetURCBValues(IEC61850 client, unsigned int serverIndex, char* urcbReference, GetURCBValues_Response* response);

/*!	\brief	设置缓存报告控制块值。
	\details
	对应的 ACSI 服务接口为：\"SetBRCBValues\"。<br>
	该接口为客户端使用的接口，服务端禁止调用。<br>
	`request` 和 `response` 参数需要根据设置的 BRCB 实例数量进行构建。具体可参照对应数据类型的说明。

	\ingroup	BRCB

	\param[in]		client		IEC61850 对象。<br>对象角色必须是客户端 `IEC61850_CLIENT`
	\param[in]		serverIndex	服务端的索引号
	\param[in]		request		ACSI 服务接口 SetBRCBValues 的请求数据。<br>请求设置的 BRCB 的值。
	\param[in,out]	response	ACSI 服务接口 SetBRCBValues 的响应数据。<br>设置的 BRCB 值对应的响应结果。

	\return		错误码。<br>成功则返回  #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	\note
	已经被客户端占用了的报告控制块实例，仅能由占有该实例的客户端来设置。

	<b>示例</b>
	\code
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_SetBRCBValues(IEC61850 client, unsigned int serverIndex, SetBRCBValues_Request* request, SetBRCBValues_Response* response);

/*!	\brief	设置非缓存报告控制块值。
	\details
	对应的 ACSI 服务接口为：\"SetURCBValues\"。<br>
	该接口为客户端使用的接口，服务端禁止调用。<br>
	`request` 和 `response` 参数需要根据设置的 URCB 实例数量进行构建。具体可参照对应数据类型的说明。

	\ingroup	URCB

	\param[in]		client		IEC61850 对象。<br>对象角色必须是客户端 `IEC61850_CLIENT`
	\param[in]		serverIndex	服务端的索引号
	\param[in]		request		ACSI 服务接口 SetURCBValues 的请求数据。<br>请求设置的 URCB 的值。
	\param[in,out]	response	ACSI 服务接口 SetURCBValues 的响应数据。<br>设置的 URCB 值对应的响应结果。

	\return		错误码。<br>成功则返回  #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	\note
	已经被客户端占用了的报告控制块实例，仅能由占有该实例的客户端来设置。

	<b>示例</b>
	\code
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_SetURCBValues(IEC61850 client, unsigned int serverIndex, SetURCBValues_Request* request, SetURCBValues_Response* response);

/*!	\brief	获取控制块句柄信息。
	\details
	该接口用于获取控制块的句柄。<br>
	获取的控制块句柄，用于 IEC61850_GetControlBlockDataList 和 IEC61850_BatchUpdateControlBlockDatas 接口的使用。<br>
	该接口为服务端使用的接口，客户端禁止调用。

	\ingroup	ControlBlock

	\param[in]	server			IEC61850 对象。<br>对象角色必须是服务端 `IEC61850_SERVER`
	\param[in]	cbReference		控制块的引用
	\param[out]	cbHandleInfo	控制块句柄信息，即是入参也是出参。需要定义零值的 #IEC61850_CBHandleInfo 结构体数据作为出入参传参。

	\return		错误码。<br>成功则返回  #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	<b>示例</b>
	\code
	IEC61850_ErrorCode result = S_OK;
	IEC61850 server = GetMyServerClient();
	char* cbReference = "ServerIEDExample/CSWI0.BufferedCB";
	IEC61850_CBHandleInfo cbHandleInfo ={ 0 };

	cbHandleInfo.controlBlockType = CONTROLBLOCK_REPORT;
	cbid.index = 1;
	result = IEC61850_GetControlBlockHandle(server, cbReference, &cbHandleInfo);
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_GetControlBlockHandle(IEC61850 server, char* cbReference, IEC61850_CBHandleInfo* cbHandleInfo);

/*!	\brief	该接口用于获取服务端报告控制块数据。
	\ingroup	ControlBlock

	\param[in]	server			IEC61850 对象。<br>对象角色必须是服务端 `IEC61850_SERVER`
	\param[in]	rcbReference	报告控制块ref引用
	\param[in]	reportInstanceIndex	报告控制块实例索引
	\param[in,out]  rcbValues  服务端报告控制块数据

	\return		错误码。<br>成功则返回  #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。
*/
PIS10_API IEC61850_ErrorCode IEC61850_GetLocalServerRCBValues(IEC61850 server, char* rcbReference, unsigned int reportInstanceIndex, RCBValues* rcbValues);

/*!	\brief	该接口用于获取服务端控制数据。
	\ingroup	ControlBlock

	\param[in]	server			IEC61850 对象。<br>对象角色必须是服务端 `IEC61850_SERVER`
	\param[in]	ctlReference	控制ref引用
	\param[in,out]  ctlInfo		服务端控制数据

	\return		错误码。<br>成功则返回  #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。
*/
PIS10_API IEC61850_ErrorCode IEC61850_GetLocalServerControlInfo(IEC61850 server, char* ctlReference, ControlInfo* ctlInfo);

/*!	\brief	该接口用于客户端（直连接）设置通讯参数。
	\ingroup	Management

	\param[in]	client			IEC61850 对象。<br>对象角色必须是客户端 `IEC61850_CLIENT`
	\param[in]	apIndex			AP访问点索引
	\param[in]  ip				IP地址
	\param[in]  macAddress		MAC地址

	\return		错误码。<br>成功则返回  #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。
*/
PIS10_API IEC61850_ErrorCode IEC61850_SetLocalClientAddress(IEC61850 client, unsigned int apIndex, char* ip, char* macAddress);

/*!	\brief	该接口用于客户端（直连接）设置服务端通讯参数。
	\ingroup	Management

	\param[in]	client			IEC61850 对象。<br>对象角色必须是客户端 `IEC61850_CLIENT`
	\param[in]	serverIndex		服务端的索引号
	\param[in]  ip				服务端IP地址
	\param[in]  port			端口

	\return		错误码。<br>成功则返回  #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。
*/
PIS10_API IEC61850_ErrorCode IEC61850_SetRemoteServerAddress(IEC61850 client, unsigned int serverIndex, char* ip, int port);

/*!	\brief	该接口用于客户端（直连接）断开通讯。
	\ingroup	Management

	\param[in]	client			IEC61850 对象。<br>对象角色必须是客户端 `IEC61850_CLIENT`
	\param[in]	serverIndex		服务端的索引号

	\return		错误码。<br>成功则返回  #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。
*/
PIS10_API IEC61850_ErrorCode IEC61850_DisconnectServer(IEC61850 client, unsigned int serverIndex);

/*!	\brief	该接口用于客户端（直连接）重连服务。
	\ingroup	Management

	\param[in]	client			IEC61850 对象。<br>对象角色必须是客户端 `IEC61850_CLIENT`
	\param[in]	serverIndex		服务端的索引号

	\return		错误码。<br>成功则返回  #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。
*/
PIS10_API IEC61850_ErrorCode IEC61850_ReconnectServer(IEC61850 client, unsigned int serverIndex);

/*!	\brief	该接口用于服务端本地设置定值。
	\ingroup	SGCB

	\param[in]	server			IEC61850 对象。<br>对象角色必须是服务端 `IEC61850_SERVER`
	\param[in]	daid			数据ID
	\param[in]	dataValues		数据
	\param[in]	actNumber		定制组索引号	
	
	\return		错误码。<br>成功则返回  #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。
*/
PIS10_API IEC61850_ErrorCode IEC61850_SetSettingGroupDataValue(IEC61850 server, IEC61850_DataAttributeID* daid, IEC61850_DataAttributeData* dataValues, U8 actNumber);

/*!	\brief	该接口释放IEC61850_DataAttributeData内存(批量)。
	\ingroup	DataAttributeAccess

	\param[in,out]	dataAttributes		数据属性
	\param[in]		numOfDataAttributes	数据长度

	\return		错误码。<br>成功则返回  #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。
*/
PIS10_API IEC61850_ErrorCode FreeDataAttributeDatas(IEC61850_DataAttributeData* dataAttributes, U32 numOfDataAttributes);

/*!	\brief	该接口释放IEC61850_DataAttributeData内存(批量)。
	\ingroup	DataAttributeAccess

	\param[in,out]	response	数据返回值

	\return		错误码。<br>成功则返回  #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。
*/
PIS10_API IEC61850_ErrorCode FreeSetDataSetValues_Response(SetDataSetValues_Response* response);

/*!	\brief	该接口释放IEC61850_DataAttributeData内存。
	\ingroup	DataAttributeAccess

	\param[in,out]	dataAttribute	数据属性

	\return		错误码。<br>成功则返回  #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。
*/
PIS10_API IEC61850_ErrorCode FreeDataAttributeData(IEC61850_DataAttributeData* dataAttribute);

/*!	\brief	该接口获取数据属性访问句柄
	\ingroup	DataAttributeAccess

	\param[in]	server					IEC61850 对象。<br>对象角色必须是服务端 `IEC61850_SERVER`
	\param[in]	reference				引用地址

	\return		内部命名变量句柄。
*/
PIS10_API DAHANDLE IEC61850_GetDataAttributeHandle(IEC61850 server, char* reference);

/*!	\brief	该接口获取日志状态
	\ingroup	LCB

	\param[in]	logCbHandle				日志控制块句柄
	\param[in,out]	logStatus			日志状态

	\return		错误码。<br>成功则返回  #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。
*/
PIS10_API IEC61850_ErrorCode IEC61850_GetLocalLogStatus(CBHANDLE logCbHandle, IEC61850_LogStatus* logStatus);

/*!	\brief	基于控制块句柄获取控制块关联数据集的基本类型数据列表
	\ingroup	ControlBlock

	\param[in]	server					IEC61850 对象。<br>对象角色必须是服务端 `IEC61850_SERVER`
	\param[in]	cbHandleInfo			控制块句柄
	\param[out]	controlBlockDataList	控制块关联数据集的基本类型数据列表

	\return		错误码。<br>成功则返回  #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	<b>示例</b>
	\code
	IEC61850_ErrorCode result = S_OK;
	IEC61850 iec61850 = GetMyServerClient();
	IEC61850_ControlBlockDataList controlBlockDataList = { 0 };
	IEC61850_CBHandleInfo cbHandleInfo = { 0 };
	char* cbReference = "ServerIEDExample/MMXU0.Measurement";

	cbHandleInfo.controlBlockType = CONTROLBLOCK_REPORT;
	cbHandleInfo.index = 1;
	result = IEC61850_GetControlBlockHandle(iec61850, cbReference, &cbHandleInfo);
	if (result == S_OK) {
		result = IEC61850_GetControlBlockDataList(iec61850, &cbHandleInfo, &controlBlockDataList);
		if (controlBlockDataList.datasetDatas) {
			for (unsigned int dataIndex = 0; dataIndex < controlBlockDataList.numOfDatas; dataIndex++) {
				printf("NO.%u:\n", dataIndex);
				printf("  reference:%s\n", controlBlockDataList.datasetDatas[dataIndex].dataReference);
				printf("  Data index in dataset:%d\n", controlBlockDataList.datasetDatas[dataIndex].dataIndexInDataset);
				printf("  Data type:%d\n", controlBlockDataList.datasetDatas[dataIndex].data.type);
				printf("  Data size:%d\n", controlBlockDataList.datasetDatas[dataIndex].data.bitLength);
			}
		}
	}
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_GetControlBlockDataList(IEC61850 server, IEC61850_CBHandleInfo* cbHandleInfo, IEC61850_ControlBlockDataList* controlBlockDataList);

/*!	\brief	使用控制块句柄批量发送控制块数据, 例如报告和GOOSE
	\ingroup	ControlBlock

	\param[in]	server			IEC61850 对象。<br>对象角色必须是服务端 `IEC61850_SERVER`
	\param[in]	cbHandleInfo	控制块句柄
	\param[in]	dataList		控制块关联数据集的基本类型数据列表

	\return		错误码。<br>成功则返回  #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	<b>示例</b>
	\code
	IEC61850_ErrorCode result = S_OK;
	S32 Magi1 = 1;
	S32 Magi2 = 2;
	S32 Magi3 = 3;
	IEC61850_QualityFlag Quality1 = IEC61850_QUALITY_OVERFLOW;
	IEC61850_QualityFlag Quality2 = IEC61850_QUALITY_OUTOFRANGE;
	IEC61850_QualityFlag Quality3 = IEC61850_QUALITY_GOOD;
	IEC61850_TimeStamp Time1 = { 0 };
	IEC61850_TimeStamp Time2 = { 0 };
	IEC61850_TimeStamp Time3 = { 0 };

	IEC61850 iec61850 = GetMyServerClient();
	IEC61850_ControlBlockDataList controlBlockDataList = { 0 };
	IEC61850_CBHandleInfo cbHandleInfo = { 0 };
	char* cbReference = "ServerIEDExample/MMXU0.Measurement";

	cbHandleInfo.controlBlockType = CONTROLBLOCK_REPORT;
	cbHandleInfo.index = 1;
	result = IEC61850_GetControlBlockHandle(iec61850, cbReference, &cbHandleInfo);
	if (result == S_OK) {
	result = IEC61850_GetControlBlockDataList(iec61850, &cbHandleInfo, &controlBlockDataList);
	}
	controlBlockDataList.datasetDatas[0].data.pvData = &Magi1;
	controlBlockDataList.datasetDatas[1].data.pvData = &Quality1;
	controlBlockDataList.datasetDatas[2].data.pvData = &Time1;
	controlBlockDataList.datasetDatas[3].data.pvData = &Magi2;
	controlBlockDataList.datasetDatas[4].data.pvData = &Quality2;
	controlBlockDataList.datasetDatas[5].data.pvData = &Time2;
	controlBlockDataList.datasetDatas[6].data.pvData = &Magi3;
	controlBlockDataList.datasetDatas[7].data.pvData = &Quality3;
	controlBlockDataList.datasetDatas[8].data.pvData = &Time3;

	result = IEC61850_BatchUpdateControlBlockDatas(iec61850, &cbHandleInfo, &controlBlockDataList);
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_BatchUpdateControlBlockDatas(IEC61850 server, IEC61850_CBHandleInfo* cbHandleInfo, IEC61850_ControlBlockDataList* dataList);

/*!	\brief	本地选择激活定值组。
	\details
	该接口为服务端使用的接口，客户端禁止调用。

	\ingroup	SGCB

	\param[in]	server			IEC61850 对象。对象角色必须是服务端
	\param[in]	sgcbReference	定值组控制块的引用
	\param[in]	sgNum			选择激活组的编号

	\return		成功返回 0，失败返回 #eServiceError 对应的代码

	<b>示例</b>
	\code
	eServiceError serviceErr = S_OK;
	IEC61850 iec61850 = GetMyServerClient();
	char* sgcbRef = "ServerIEDExample/LLN0.SGCB";
	U8 sgNum = 2;

	serviceErr = IEC61850_LocalSelectActiveSG(iec61850, sgcbRef, sgNum);
	\endcode
*/
PIS10_API eServiceError IEC61850_LocalSelectActiveSG(IEC61850 server, char* sgcbReference, U8 sgNum);

/*!	\brief	本地选择编辑定值组。
	\details
	该接口为服务端使用的接口，客户端禁止调用。

	\ingroup	SGCB

	\param[in]	server			IEC61850 对象。对象角色必须是服务端
	\param[in]	sgcbReference	定值组控制块的引用
	\param[in]	sgNum			选择编辑组的编号

	\return		成功返回 0，失败返回 #eServiceError 对应的代码

	<b>示例</b>
	\code
	U8 sgNum = 2;
	eServiceError result = IEC61850_LocalSelectEditSG(GetMyServerClient(), "ServerIEDExample/LLN0.SGCB", sgNum);
	\endcode
*/
PIS10_API eServiceError IEC61850_LocalSelectEditSG(IEC61850 server, char* sgcbReference, U8 sgNum);

/*!	\brief	本地设置定值组值。
	\details
	该接口为服务端使用的接口，客户端禁止调用。

	\ingroup	SGCB

	\param[in]	server			IEC61850 对象。对象角色必须是服务端
	\param[in]	dataRef			定值组数据的引用，必须引用到最基本类型，数组必须携带下标
	\param[in]	dataAttribute	设置的数据

	\return		成功返回 0，失败返回 #eServiceError 对应的代码

	<b>示例</b>
	\code
	IEC61850_DataAttributeData data = { 0 };
	S32 newVal = 123;
	IEC61850_SetDataInt32(&data, &newVal);
	eServiceError serviceErr = IEC61850_LocalSetEditSGValue(GetMyServerClient(), 
			"ServerIEDExample/IARC0.MemFull.setVal", &data);
	\endcode
*/
PIS10_API eServiceError IEC61850_LocalSetEditSGValue(IEC61850 server, char* dataRef, IEC61850_DataAttributeData* dataAttribute);

/*!	\brief	本地确认编辑定值组。
	\details
	该接口为服务端使用的接口，客户端禁止调用。

	\ingroup	SGCB

	\param[in]	server			IEC61850 对象。对象角色必须是服务端
	\param[in]	sgcbReference	定值组控制块的引用

	\return		成功返回 0，失败返回 #eServiceError 对应的代码

	<b>示例</b>
	\code
	eServiceError serviceErr = IEC61850_LocalConfirmEditSGValues(GetMyServerClient(), "ServerIEDExample/LLN0.SGCB");
	\endcode
*/
PIS10_API eServiceError IEC61850_LocalConfirmEditSGValues(IEC61850 server, char* sgcbReference);

/*!	\brief	获取IED名称列表。
	\ingroup	DataAttributeAccess

	\param[in]		iec61850	IEC61850 对象
	\param[in,out]	outValue	IED名称。应使用一个长度不少于 65 的字符串数组(例如 `char iedName[65]`)来接收数据。
	\param[in]		length		outValue内存长度。该参数现状未使用，且需要指定为大于 0 的值，未来将会删除该参数。

	\return		错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	<b>示例</b>
	\code
	char iedName[OBJECT_NAME_STRING_LEN+1] = { 0 };
	if (IEC61850_GetIEDName(GetMyServerClient(), iedName, OBJECT_NAME_STRING_LEN) == S_OK) {
		printf("IED name:%s", iedName);
	}
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_GetIEDName(IEC61850 iec61850, char* outValue, int length);

/*!	\brief	基于数据属性的ID(DAID)，获取数据属性的引用。
	\details
	该接口为服务端使用的接口。

	\ingroup	DataAttributeAccess

	\param[in]		server		IEC61850 对象。对象角色必须是服务端
	\param[in]		daid		数据属性的ID
	\param[in,out]	outRef		短地址对应的数据属性的引用。应使用一个长度不少于 130 的字符串数组(例如 `char ref[130]`)来接收数据。
	\param[in]		length		outRef内存长度

	\return		错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	<b>示例</b>
	\code
	IEC61850_DataAttributeID daid = { 1, 2, 3, 4, 5 };
	char ref[OBJECT_REFERENCE_STRING_LEN + 1] = { 0 };
	if (IEC61850_GetReferenceByDAID(server, &daid, ref, OBJECT_REFERENCE_STRING_LEN) == S_OK) {
		printf("ref = %s\n", ref);
	}
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_GetReferenceByDAID(IEC61850 server, IEC61850_DataAttributeID* daid, char* outRef, int length);

/*!	\brief	基于数据属性的短地址，获取数据属性的引用。
	\details
	该接口为服务端使用的接口。

	\ingroup	DataAttributeAccess

	\param[in]		server		IEC61850 对象。对象角色必须是服务端
	\param[in]		sAddr		数据属性的短地址（sAddr）
	\param[in,out]	outValue	短地址对应的数据属性的引用。应使用一个长度不少于 130 的字符串数组(例如 `char ref[130]`)来接收数据。
	\param[in]		length		outValue内存长度

	\return		错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	<b>示例</b>
	\code
	char ref[OBJECT_REFERENCE_STRING_LEN + 1] = { 0 };
	if (IEC61850_GetReferenceByShortAddr(server, "sAddrExample", ref, OBJECT_REFERENCE_STRING_LEN) == S_OK) {
		printf("ref = %s\n", ref);
	}
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_GetReferenceByShortAddr(IEC61850 server, char* sAddr, char* outValue, int length);

/*!	\brief	基于引用获取数据属性值。
	\details
	该接口为服务端使用的接口。

	\ingroup	DataAttributeAccess

	\param[in]		server		IEC61850 对象。对象角色必须是服务端
	\param[in]		ref			引用字符串
	\param[in,out]	outValue	数据属性返回值

	\return		错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	<b>示例</b>
	\code
	IEC61850_DataAttributeData data = { 0 };
	if (IEC61850_GetDataAttributeDataByReference(server, "ServerIEDExample/LLN0.Mod.stVal", &data) == S_OK) {
		printf("type=%d, bitLength=%d, arrayIndex=%d\n", (int)data.type, data.bitLength, data.arrayIndex);
	}
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_GetDataAttributeDataByReference(IEC61850 server, char* ref, IEC61850_DataAttributeData* outValue);

/*!	\brief	基于数据属性的ID，获取数据属性的短地址。
	\details
	该接口为服务端使用的接口。

	\ingroup	DataAttributeAccess

	\param[in]		server		IEC61850 对象。对象角色必须是服务端
	\param[in]		ref			数据属性的引用
	\param[out]		daid		引用对应的数据属性的ID（DAID）

	\return		错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	<b>示例</b>
	\code
	IEC61850_DataAttributeID daid = { 0 };
	if (IEC61850_GetShortAddrByReference(GetMyServerClient(), "ServerIEDExample/MMXU0.A.phsA.cVal.mag.i", &daid) == S_OK) {
		printf("ref = %s\n", sAddr);
	}
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_GetDAIDByReference(IEC61850 server, char* ref, IEC61850_DataAttributeID* daid);

/*!	\brief	基于数据属性的引用，获取数据属性的短地址。
	\details
	该接口为服务端使用的接口。

	\ingroup	DataAttributeAccess

	\param[in]		server		IEC61850 对象。对象角色必须是服务端
	\param[in]		ref			数据属性的引用
	\param[in,out]	outValue	引用对应的数据属性的短地址（sAddr）
	\param[in]		length		outValue内存长度

	\return		错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	<b>示例</b>
	\code
	char sAddr[100] = {0};
	if (IEC61850_GetShortAddrByReference(GetMyServerClient(), "ServerIEDExample/MMXU0.A.phsA.cVal.mag.i", sAddr, 129) == S_OK) {
		printf("ref = %s\n", sAddr);
	}
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_GetShortAddrByReference(IEC61850 server, char* ref, char* outValue, int length);

/*!	\brief	获取 IEC61850 对象对应的数据映射模式。
	\ingroup	Support

	\param[in]	iec61850	IEC61850 对象

	\return		返回 IEC61850 对象对应的数据映射模式，对应 #IEC61850_DataMapMode 的枚举值。
*/
PIS10_API IEC61850_DataMapMode IEC61850_GetDataMapMode(IEC61850 iec61850);

/*!	\brief	读服务器目录。
	\details
	对应的 ACSI 服务接口为：\"GetServerDirectory\"。<br>
	该接口为客户端使用的接口，服务端禁止调用。

	\ingroup	Support

	\param[in]		client		IEC61850 对象。对象角色必须是客户端 IEC61850_CLIENT
	\param[in]		serverIndex	服务端的索引号
	\param[in]		request		ACSI 服务接口 GetServerDirectory 的请求数据
	\param[in,out]	response	ACSI 服务接口 GetServerDirectory 的响应数据

	\return		错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	\see	FreeGetServerDirectory_Response()
*/
PIS10_API IEC61850_ErrorCode IEC61850_GetServerDirectory(IEC61850 client, unsigned int serverIndex, GetServerDirectory_Request* request, GetServerDirectory_Response* response);

/*!	\brief	读逻辑设备目录。
	\details
	对应的 ACSI 服务接口为：\"GetLogicalDeviceDirectory\"。<br>
	该接口为客户端使用的接口，服务端禁止调用。

	\ingroup	Support

	\param[in]		client		IEC61850 对象。对象角色必须是客户端 IEC61850_CLIENT
	\param[in]		serverIndex	服务端的索引号
	\param[in]		request		ACSI 服务接口 GetLogicalDeviceDirectory 的请求数据
	\param[in,out]	response	ACSI 服务接口 GetLogicalDeviceDirectory 的响应数据

	\return		错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	\see	FreeGetLogicalDeviceDirectory_Response()
*/
PIS10_API IEC61850_ErrorCode IEC61850_GetLogicalDeviceDirectory(IEC61850 client, unsigned int serverIndex, GetLogicalDeviceDirectory_Request* request, GetLogicalDeviceDirectory_Response* response);

/*!	\brief	读逻辑节点目录。
	\details
	对应的 ACSI 服务接口为：\"GetLogicalNodeDirectory\"。<br>
	该接口为客户端使用的接口，服务端禁止调用。

	\ingroup	Support

	\param[in]		client		IEC61850 对象。对象角色必须是客户端 IEC61850_CLIENT
	\param[in]		serverIndex	服务端的索引号
	\param[in]		request		ACSI 服务接口 GetLogicalNodeDirectory 的请求数据
	\param[in,out]	response	ACSI 服务接口 GetLogicalNodeDirectory 的应答数据

	\return		错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	\see	FreeGetLogicalNodeDirectory_Response()
*/
PIS10_API IEC61850_ErrorCode IEC61850_GetLogicalNodeDirectory(IEC61850 client, unsigned int serverIndex, GetLogicalNodeDirectory_Request* request, GetLogicalNodeDirectory_Response* response);

/*!	\brief	读所有数据值。
	\details
	对应的 ACSI 服务接口为：\"GetAllDataValues\"。<br>
	该接口为客户端使用的接口，服务端禁止调用。

	\ingroup	Support

	\param[in]		client		IEC61850 对象。对象角色必须是客户端 IEC61850_CLIENT
	\param[in]		serverIndex	服务端的索引号
	\param[in]		request		ACSI 服务接口 GetAllDataValues 的请求数据
	\param[in,out]	response	ACSI 服务接口 GetAllDataValues 的应答数据

	\return		错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。
*/
PIS10_API IEC61850_ErrorCode IEC61850_GetAllDataValues(IEC61850 client, unsigned int serverIndex, GetAllData_Request* request, GetAllDataValues_Response* response);

/*!	\brief	读所有数据定义。
	\details
	对应的 ACSI 服务接口为：\"GetAllDataDefinition\"。<br>
	该接口为客户端使用的接口，服务端禁止调用。

	\ingroup	Support

	\param[in]		client		IEC61850 对象。对象角色必须是客户端 IEC61850_CLIENT
	\param[in]		serverIndex	服务端的索引号
	\param[in]		request		ACSI 服务接口 GetAllDataDefinition 的请求数据
	\param[in,out]	response	ACSI 服务接口 GetAllDataDefinition 的应答数据

	\return		错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。
*/
PIS10_API IEC61850_ErrorCode IEC61850_GetAllDataDefinition(IEC61850 client, unsigned int serverIndex, GetAllData_Request* request, GetAllDataDefinition_Response* response);

/*!	\brief	读所有控制块的值。
	\details
	对应的 ACSI 服务接口为：\"GetAllCBValues\"。<br>
	该接口为客户端使用的接口，服务端禁止调用。

	\ingroup	Support

	\param[in]		client		IEC61850 对象。对象角色必须是客户端 IEC61850_CLIENT
	\param[in]		serverIndex	服务端的索引号
	\param[in]		request		ACSI 服务接口 GetAllCBValues 的请求数据
	\param[in,out]	response	ACSI 服务接口 GetAllCBValues 的应答数据

	\return		错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。
*/
PIS10_API IEC61850_ErrorCode IEC61850_GetAllCBValues(IEC61850 client, unsigned int serverIndex, GetAllCBValues_Request* request, GetAllCBValues_Response* response);

/*!	\brief	获取数据值。
	\details
	对应的 ACSI 服务接口为：\"GetDataValues\"。<br>
	该接口为客户端使用的接口，服务端禁止调用。

	\ingroup	DataSet

	\param[in]		client		IEC61850 对象。<br>对象角色必须是客户端 `IEC61850_CLIENT`
	\param[in]		serverIndex	服务端的索引号
	\param[in]		request		ACSI 服务接口 GetDataValues 的请求数据。<br>数据的引用。
	\param[in,out]	response	ACSI 服务接口 GetDataValues 的返回数据。<br>数据的值。

	\return		错误码。<br>成功则返回  #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	<b>示例</b>
	\code
	IEC61850_ErrorCode result = S_OK;
	IEC61850 iec61850 = GetMyServerClient();
	GetDataSetValues_Response response = { 0 };
	GetDataValues_Request request = { 0 };
	GetDataValues_Response respon = { 0 };
	FCDA fcda[2] = { 0 };

	request.dataNum = 2;
	request.FCDAs = &fcda;
	fcda[0].fc = "MX";
	fcda[0].reference = "ServerIEDExample/MMXU0.A";
	fcda[1].fc = "MX";
	fcda[1].reference = "ServerIEDExample/MMXU0.A.phsA.cVal.mag.i";

	IEC61850_GetDataValues(iec61850, 0, &request, &respon);

	PrintDAVal(respon.dataAttributes, 2);
	FreeDataAttributeDatas(respon.dataAttributes, respon.dataNum);
	free(respon.dataAttributes);
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_GetDataValues(IEC61850 client, unsigned int serverIndex, GetDataValues_Request* request, GetDataValues_Response* response);

/*!	\brief	写数据值。
	\details
	对应的 ACSI 服务接口为：\"SetDataValues\"。<br>
	该接口为客户端使用的接口，服务端禁止调用。

	\ingroup	Support

	\param[in]		client		IEC61850 对象。对象角色必须是客户端 IEC61850_CLIENT
	\param[in]		serverIndex	服务端的索引号
	\param[in]		request		ACSI 服务接口 SetDataValues 的请求数据
	\param[in,out]	response	ACSI 服务接口 SetDataValues 的响应数据

	\return		错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。
*/
PIS10_API IEC61850_ErrorCode IEC61850_SetDataValues(IEC61850 client, unsigned int serverIndex, SetDataValues_Request* request, SetDataValues_Response* response);

/*!	\brief	读数据目录。
	\details
	对应的 ACSI 服务接口为：\"GetDataDirectory\"。<br>
	该接口为客户端使用的接口，服务端禁止调用。

	\ingroup	Support

	\param[in]		client		IEC61850 对象。对象角色必须是客户端 IEC61850_CLIENT
	\param[in]		serverIndex	服务端的索引号
	\param[in]		request		ACSI 服务接口 GetDataDirectory 的请求
	\param[in,out]	response	ACSI 服务接口 GetDataDirectory 的应答

	\return		错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。
*/
PIS10_API IEC61850_ErrorCode IEC61850_GetDataDirectory(IEC61850 client, unsigned int serverIndex, GetDataDirectory_Request* request, GetDataDirectory_Response* response);

/*!	\brief	读数据定义。
	\details
	对应的 ACSI 服务接口为：\"GetDataDefinition\"。<br>
	该接口为客户端使用的接口，服务端禁止调用。

	\ingroup	Support

	\param[in]		client		IEC61850 对象。对象角色必须是客户端 IEC61850_CLIENT
	\param[in]		serverIndex	服务端的索引号
	\param[in]		request		ACSI 服务接口 GetDataDefinition 的请求数据
	\param[in,out]	response	ACSI 服务接口 GetDataDefinition 的应答数据

	\return		错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。
*/
PIS10_API IEC61850_ErrorCode IEC61850_GetDataDefinition(IEC61850 client, unsigned int serverIndex, GetDataDefinition_Request* request, GetDataDefinition_Response* response);

/*!	\brief	用于客户端服务发现，遍历服务端的数据点。
	\ingroup	Support

	\param[in]		client		IEC61850 对象
	\param[in]		serverIndex	服务端索引
	\param[in]		domainName	请求查询层级的 DomainName
	\param[in]		level		#IEC61850_QueryLevel 查询级别{1=SERVER_DIR, 2=LD_DIR, 3=LN_DIR, 4=LN_DATASET, 5=LOG}
	\param[in,out]	ss			数据点列表

	\return		错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。
*/
PIS10_API IEC61850_ErrorCode IEC61850_GetNamedList(IEC61850 client, unsigned int serverIndex, char* domainName, IEC61850_QueryLevel level, StringList* ss);

/*!	\brief	用于客户端服务发现，查询数据点的属性信息。
	\ingroup	Support

	\param[in]		client			IEC61850 对象
	\param[in]		serverIndex		服务端索引
	\param[in]		domainName		请求查询层级的 DomainName
	\param[in]		reference		数据点对应的 ItemName
	\param[in,out]	dataTypeInfo	查询结果-数据类型

	\return		错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。
*/
PIS10_API IEC61850_ErrorCode IEC61850_GetVariableAccessAttributes(IEC61850 client, unsigned int serverIndex, char* domainName, char* reference, IEC61850_DataTypeInfo* dataTypeInfo);

/*!	\brief	释放 #IEC61850_DataTypeInfo 对象内存。
	\ingroup	Support

	\param[in]	dataTypeInfo	查询结果-数据类型

	\return		错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。
*/
PIS10_API IEC61850_ErrorCode IEC61850_FreeDataTypeInfo(IEC61850_DataTypeInfo* dataTypeInfo);

/*!	\brief	MMS引用转61850引用。
	\ingroup	Support

	\param[in]		mmsReference	MMS 引用
	\param[in,out]	outReference	IEC61850 引用。需要使用长度大于等于 130 的 char 数组来接收转换后的 IEC61850 引用字符串
	\param[in,out]	outFC			功能约束。需要使用长度大于等于 3 的 char 数组来接收转换后的功能约束字符串。可指定为 NULL 来忽略该出参。

	\return		错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	<b>示例</b>
	\code
	char* mmsReference = "ServerIEDExample/CSWI0$ST$Pos$stVal";
	char reference[OBJECT_REFERENCE_STRING_LEN + 1] = { 0 };
	char fc[3] = { 0 };
	IEC61850_ErrorCode err = IEC61850_ERROR_NONE;
	err = IEC61850_ReferenceMMSToIEC61850(mmsReference, reference, fc);
	if (err == IEC61850_ERROR_NONE) {
		printf("reference: [%s], fc: [%s]\n", reference, fc);
	}
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_ReferenceMMSToIEC61850(char* mmsReference, char* outReference, char* outFC);

/*!	\brief	该接口用于快速构建对应数据类型的 IEC61850_DataAttributeData 数据。
	\details
	本接口目的在于规避用户构建 IEC61850_DataAttributeData 数据时，需要依据不同数据类型来手动指定响应的数据长度的麻烦。

	\ingroup	Support

	\param[in]	daData	数据属性对象要赋值的 IEC61850_DataAttributeData
	\param[in]	type	数据类型。指定为 #IEC61850_DataType 的枚举值。
	\param[in]	data	要赋值赋值给 daData 的数据的地址。

	\return		错误码。<br>成功则返回 #IEC61850_ERROR_NONE (0)；<br>失败则返回其他非 0 值的 #IEC61850_ErrorCode 错误码。

	<b>示例</b>
	\code
	IEC61850_DataAttributeData data = { 0 };
	S32 val = 0;
	IEC61850_DataType type = IEC61850_DATATYPE_INT32;
	IEC61850_SetDataAttributeData(&data, type, &val);
	\endcode
*/
PIS10_API IEC61850_ErrorCode IEC61850_SetDataAttributeData(IEC61850_DataAttributeData* daData, IEC61850_DataType type, void* data);

/*!	\brief	设置布尔类型数据(宏定义)
	\def	IEC61850_SetDataBoolean(data, p)
	\see	IEC61850_SetDataAttributeData(), IEC61850_DataAttributeData
   
   <b>示例</b>
  	\code
  	IEC61850_DataAttributeData data = { 0 };
  	Boolean val = TRUE;
  	IEC61850_SetDataBoolean(&data, &val);
  	\endcode
 */ 
#define IEC61850_SetDataBoolean(data, p) IEC61850_SetDataAttributeData((data), IEC61850_DATATYPE_BOOLEAN, (p))

/*!	\brief	设置INT8类型数据(宏定义)
	\see	IEC61850_SetDataAttributeData(), IEC61850_DataAttributeData
  
   <b>示例</b>
  	\code
  	IEC61850_DataAttributeData data = { 0 };
  	S8 val = 1;
  	IEC61850_SetDataInt8(&data, &val);
  	\endcode
 */
#define IEC61850_SetDataInt8(data, p) IEC61850_SetDataAttributeData((data), IEC61850_DATATYPE_INT8, (p))

/*!	\brief	设置有无符号INT8U类型数据(宏定义)
	\see	IEC61850_SetDataAttributeData(), IEC61850_DataAttributeData
  
   <b>示例</b>
  	\code
  	IEC61850_DataAttributeData data = { 0 };
  	U8 val = 1;
  	IEC61850_SetDataInt8U(&data, &val);
  	\endcode
 */
#define IEC61850_SetDataInt8U(data, p) IEC61850_SetDataAttributeData((data), IEC61850_DATATYPE_INT8U, (p))

/*!	\brief	设置INT16类型数据(宏定义)
	\see	IEC61850_SetDataAttributeData(), IEC61850_DataAttributeData
  
   <b>示例</b>
  	\code
  	IEC61850_DataAttributeData data = { 0 };
  	S16 val = 1;
  	IEC61850_SetDataInt16(&data, &val);
  	\endcode
 */
#define IEC61850_SetDataInt16(data, p) IEC61850_SetDataAttributeData((data), IEC61850_DATATYPE_INT16, (p))

/*!	\brief	设置INT32类型数据(宏定义)
	\see	IEC61850_SetDataAttributeData(), IEC61850_DataAttributeData
  
   <b>示例</b>
  	\code
  	IEC61850_DataAttributeData data = { 0 };
  	S32 val = 1;
  	IEC61850_SetDataInt32(&data, &val);
  	\endcode
 */
#define IEC61850_SetDataInt32(data, p) IEC61850_SetDataAttributeData((data), IEC61850_DATATYPE_INT32, (p))

/*!	\brief	设置INT64类型数据(宏定义)
	\see	IEC61850_SetDataAttributeData(), IEC61850_DataAttributeData
  
   <b>示例</b>
  	\code
  	IEC61850_DataAttributeData data = { 0 };
  	S64 val = 1;
  	IEC61850_SetDataInt64(&data, &val);
  	\endcode
 */
#define IEC61850_SetDataInt64(data, p) IEC61850_SetDataAttributeData((data), IEC61850_DATATYPE_INT64, (p))

/*!	\brief	设置无符号INT16U类型数据(宏定义)
	\see	IEC61850_SetDataAttributeData(), IEC61850_DataAttributeData
  
   <b>示例</b>
  	\code
  	IEC61850_DataAttributeData data = { 0 };
  	U16 val = 1;
  	IEC61850_SetDataInt16U(&data, &val);
  	\endcode
 */
#define IEC61850_SetDataInt16U(data, p) IEC61850_SetDataAttributeData((data), IEC61850_DATATYPE_INT16U, (p))

/*!	\brief	设置无符号INT32U类型数据(宏定义)
	\see	IEC61850_SetDataAttributeData(), IEC61850_DataAttributeData
  
   <b>示例</b>
  	\code
  	IEC61850_DataAttributeData data = { 0 };
  	U32 val = 1;
  	IEC61850_SetDataInt32U(&data, &val);
  	\endcode
 */
#define IEC61850_SetDataInt32U(data, p) IEC61850_SetDataAttributeData((data), IEC61850_DATATYPE_INT32U, (p))

/*!	\brief	设置浮点Float32类型数据(宏定义)
	\see	IEC61850_SetDataAttributeData(), IEC61850_DataAttributeData
  
   <b>示例</b>
  	\code
  	IEC61850_DataAttributeData data = { 0 };
  	Float32 val = 1;
  	IEC61850_SetDataFloat32(&data, &val);
  	\endcode
 */
#define IEC61850_SetDataFloat32(data, p) IEC61850_SetDataAttributeData((data), IEC61850_DATATYPE_FLOAT32, (p))

/*!	\brief	设置浮点Float64类型数据(宏定义)
	\see	IEC61850_SetDataAttributeData(), IEC61850_DataAttributeData
  
   <b>示例</b>
  	\code
  	IEC61850_DataAttributeData data = { 0 };
  	Float64 val = 1;
  	IEC61850_SetDataFloat64(&data, &val);
  	\endcode
 */
#define IEC61850_SetDataFloat64(data, p) IEC61850_SetDataAttributeData((data), IEC61850_DATATYPE_FLOAT64, (p))

/*!	\brief	设置枚举类型数据(宏定义)
	\see	IEC61850_SetDataAttributeData(), IEC61850_DataAttributeData
  
   <b>示例</b>
  	\code
  	IEC61850_DataAttributeData data = { 0 };
  	IEC61850_ModeAndBehaviourState val = 1;
    // U8 val = 1;
  	IEC61850_SetDataEnum(&data, &val);
  	\endcode
 */
#define IEC61850_SetDataEnum(data, p) IEC61850_SetDataAttributeData((data), IEC61850_DATATYPE_ENUMERATED, (p))

/*!	\brief	设置字符串类型数据(宏定义)
	\see	IEC61850_SetDataAttributeData(), IEC61850_DataAttributeData
  
   <b>示例</b>
  	\code
  	IEC61850_DataAttributeData data = { 0 };
  	char val[200] = "test";
  	IEC61850_SetDataVisibleString(&data, &val);
  	\endcode
 */
#define IEC61850_SetDataVisibleString(data, p) IEC61850_SetDataAttributeData((data), IEC61850_DATATYPE_VISIBLE_STRING, (p))

/*!	\brief	设置Unicode字符串类型数据(宏定义)
	\see	IEC61850_SetDataAttributeData(), IEC61850_DataAttributeData
  
   <b>示例</b>
  	\code
  	IEC61850_DataAttributeData data = { 0 };
  	char val[200] = "test中文";
  	IEC61850_SetDataUnicodeString(&data, &val);
  	\endcode
 */
#define IEC61850_SetDataUnicodeString(data, p) IEC61850_SetDataAttributeData((data), IEC61850_DATATYPE_UNICODE_STRING, (p))

/*!	\brief	设置时间戳类型数据(宏定义)
	\see	IEC61850_SetDataAttributeData(), IEC61850_DataAttributeData
  
   <b>示例</b>
  	\code
  	IEC61850_DataAttributeData data = { 0 };
    IEC61850_TimeStamp t = { 0 };
    IEC61850_GetTime(NULL, &t);
  	IEC61850_SetDataTimestamp(&data, &val);
  	\endcode
 */
#define IEC61850_SetDataTimestamp(data, p) IEC61850_SetDataAttributeData((data), IEC61850_DATATYPE_TIMESTAMP, (p))

/*!	\brief	设置质量类型数据(宏定义)
	\see	IEC61850_SetDataAttributeData(), IEC61850_DataAttributeData
  
   <b>示例</b>
  	\code
  	IEC61850_DataAttributeData data = { 0 };
    tIEC61850Quality val = IEC61850_QUALITY_GOOD;
  	IEC61850_SetDataQuality(&data, &val);
  	\endcode
 */
#define IEC61850_SetDataQuality(data, p) IEC61850_SetDataAttributeData((data), IEC61850_DATATYPE_QUALITY, (p))

/*!	\brief	该接口用于释放 IEC61850_GetURCBValues() 接口的响应数据。
	\ingroup	URCB

	\param[in,out]	response	IEC61850_GetURCBValues() 的响应数据

	\return		无返回值

	\see	IEC61850_GetServerDirectory()
*/
PIS10_API void FreeGetServerDirectory_Response(GetServerDirectory_Response* response);

/*!	\brief	该接口用于释放 IEC61850_GetLogicalDeviceDirectory() 接口的响应数据。
	\ingroup	URCB

	\param[in,out]	response	IEC61850_GetLogicalDeviceDirectory() 的响应数据

	\return		无返回值

	\see	IEC61850_GetLogicalDeviceDirectory()
*/
PIS10_API void FreeGetLogicalDeviceDirectory_Response(GetLogicalDeviceDirectory_Response* response);

/*!	\brief	该接口用于释放 IEC61850_GetLogicalNodeDirectory() 接口的响应数据。
	\ingroup	URCB

	\param[in,out]	response	IEC61850_GetLogicalNodeDirectory() 的响应数据

	\return		无返回值

	\see	IEC61850_GetLogicalNodeDirectory()
*/
PIS10_API void FreeGetLogicalNodeDirectory_Response(GetLogicalNodeDirectory_Response* response);

/*!	\brief	该接口用于释放 IEC61850_GetAllDataValues() 接口的响应数据。
	\ingroup	URCB

	\param[in,out]	response	IEC61850_GetAllDataValues() 的响应数据

	\return		无返回值
*/
PIS10_API void FreeGetAllDataValues_Response(GetAllDataValues_Response* response);

/*!	\brief	该接口用于释放 IEC61850_GetDataValues() 接口的响应数据。
	\ingroup	URCB

	\param[in,out]	response	IEC61850_GetDataValues() 的响应数据

	\return		无返回值
*/
PIS10_API void FreeGetDataValues_Response(GetDataValues_Response* response);

/*!	\brief	该接口用于释放 IEC61850_SetDataValues() 接口的响应数据。
	\ingroup	URCB

	\param[in,out]	response	IEC61850_SetDataValues() 的响应数据

	\return		无返回值
*/
PIS10_API void FreeSetDataValues_Response(SetDataValues_Response* response);

/*!	\brief	该接口用于释放 IEC61850_GetDataDirectory() 接口的响应数据。
	\ingroup	URCB

	\param[in,out]	response	IEC61850_GetDataDirectory() 的响应数据

	\return		无返回值
*/
PIS10_API void FreeGetDataDirectory_Response(GetDataDirectory_Response* response);

/*!	\brief	该接口用于释放 IEC61850_GetDataDefinition() 接口的响应数据。
	\ingroup	URCB

	\param[in,out]	response	IEC61850_GetDataDefinition() 的响应数据

	\return		无返回值
*/
PIS10_API void FreeGetDataDefinition_Response(GetDataDefinition_Response* response);

/*!	\brief	该接口用于释放动态分配的数据定义。
	\details
	该接口被 `FreeDataDefinitions()` 接口所使用，用于递归释放数据定义列表中的数据定义。

	\ingroup	DataAttributeAccess

	\param[in,out]	definition	数据定义

	\return		无返回值
*/
PIS10_API void FreeDataDefinition(DataDefinition* definition);

/*!	\brief	该接口用于释放获取的所有控制块值。
	\ingroup	cbValues

	\param[in,out]	cbValues	控制块值

	\return		无返回值
*/
PIS10_API void FreeAllCBValues(GetAllCBValsReturn* cbValues);

/*!	\brief	该接口用于释放获取的数据集目录。
	\ingroup	cbValues

	\param[in,out]	response	数据集目录

	\return		无返回值
*/
PIS10_API void FreeGetDataSetDirectory_Response(GetDataSetDirectory_Response* response);

/*!	\brief	该接口用于释放获取的数据集数值。
	\ingroup	cbValues

	\param[in,out]	response	数据集数值

	\return		无返回值
*/
PIS10_API void FreeGetDataSetValues_Response(GetDataSetValues_Response* response);

/*!	\brief	该接口用于释放设置缓存报告控制块返回值。
	\ingroup	cbValues

	\param[in,out]	response	设置缓存报告控制返回值

	\return		无返回值
*/
PIS10_API void FreeSetBRCBValues_Response(SetBRCBValues_Response* response);

/*!	\brief	该接口用于释放设置非缓存报告控制返回值
	\ingroup	cbValues

	\param[in,out]	response	设置非缓存报告控制返回值

	\return		无返回值
*/
PIS10_API void FreeSetURCBValues_Response(SetURCBValues_Response* response);

#ifdef __cplusplus
}
#endif

#endif
